Make app_queue AMI events more consistent. Give Join/Leave more useful names.
[asterisk/asterisk.git] / apps / app_jack.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2007 - 2008, Russell Bryant
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 /*!
20  * \file
21  * \brief Jack Application
22  *
23  * \author Russell Bryant <russell@digium.com>
24  *
25  * This is an application to connect an Asterisk channel to an input
26  * and output jack port so that the audio can be processed through
27  * another application, or to play audio from another application.
28  *
29  * \extref http://www.jackaudio.org/
30  *
31  * \note To install libresample, check it out of the following repository:
32  * <code>$ svn co http://svn.digium.com/svn/thirdparty/libresample/trunk</code>
33  *
34  * \ingroup applications
35  */
36
37 /*** MODULEINFO
38         <depend>jack</depend>
39         <depend>resample</depend>
40         <support_level>extended</support_level>
41  ***/
42
43 #include "asterisk.h"
44
45 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
46
47 #include <limits.h>
48
49 #include <jack/jack.h>
50 #include <jack/ringbuffer.h>
51
52 #include <libresample.h>
53
54 #include "asterisk/module.h"
55 #include "asterisk/channel.h"
56 #include "asterisk/strings.h"
57 #include "asterisk/lock.h"
58 #include "asterisk/app.h"
59 #include "asterisk/pbx.h"
60 #include "asterisk/audiohook.h"
61
62 #define RESAMPLE_QUALITY 1
63
64 #define RINGBUFFER_SIZE 16384
65
66 /*! \brief Common options between the Jack() app and JACK_HOOK() function */
67 #define COMMON_OPTIONS \
68 "    s(<name>) - Connect to the specified jack server name.\n" \
69 "    i(<name>) - Connect the output port that gets created to the specified\n" \
70 "                jack input port.\n" \
71 "    o(<name>) - Connect the input port that gets created to the specified\n" \
72 "                jack output port.\n" \
73 "    n         - Do not automatically start the JACK server if it is not already\n" \
74 "                running.\n" \
75 "    c(<name>) - By default, Asterisk will use the channel name for the jack client\n" \
76 "                name.  Use this option to specify a custom client name.\n"
77 /*** DOCUMENTATION
78         <application name="JACK" language="en_US">
79                 <synopsis>
80                         Jack Audio Connection Kit
81                 </synopsis>
82                 <syntax>
83                         <parameter name="options" required="false">
84                                 <optionlist>
85                                         <option name="s">
86                                                 <argument name="name" required="true">
87                                                         <para>Connect to the specified jack server name</para>
88                                                 </argument>
89                                         </option>
90                                         <option name="i">
91                                                 <argument name="name" required="true">
92                                                         <para>Connect the output port that gets created to the specified jack input port</para>
93                                                 </argument>
94                                         </option>
95                                         <option name="o">
96                                                 <argument name="name" required="true">
97                                                         <para>Connect the input port that gets created to the specified jack output port</para>
98                                                 </argument>
99                                         </option>
100                                         <option name="c">
101                                                 <argument name="name" required="true">
102                                                         <para>By default, Asterisk will use the channel name for the jack client name.</para>
103                                                         <para>Use this option to specify a custom client name.</para>
104                                                 </argument>
105                                         </option>
106                                 </optionlist>
107                         </parameter>
108                 </syntax>
109                 <description>
110                         <para>When executing this application, two jack ports will be created;
111                         one input and one output. Other applications can be hooked up to
112                         these ports to access audio coming from, or being send to the channel.</para>
113                 </description>
114         </application>
115  ***/
116
117 static const char jack_app[] = "JACK";
118
119 struct jack_data {
120         AST_DECLARE_STRING_FIELDS(
121                 AST_STRING_FIELD(server_name);
122                 AST_STRING_FIELD(client_name);
123                 AST_STRING_FIELD(connect_input_port);
124                 AST_STRING_FIELD(connect_output_port);
125         );
126         jack_client_t *client;
127         jack_port_t *input_port;
128         jack_port_t *output_port;
129         jack_ringbuffer_t *input_rb;
130         jack_ringbuffer_t *output_rb;
131         void *output_resampler;
132         double output_resample_factor;
133         void *input_resampler;
134         double input_resample_factor;
135         unsigned int stop:1;
136         unsigned int has_audiohook:1;
137         unsigned int no_start_server:1;
138         /*! Only used with JACK_HOOK */
139         struct ast_audiohook audiohook;
140 };
141
142 static const struct {
143         jack_status_t status;
144         const char *str;
145 } jack_status_table[] = {
146         { JackFailure,        "Failure" },
147         { JackInvalidOption,  "Invalid Option" },
148         { JackNameNotUnique,  "Name Not Unique" },
149         { JackServerStarted,  "Server Started" },
150         { JackServerFailed,   "Server Failed" },
151         { JackServerError,    "Server Error" },
152         { JackNoSuchClient,   "No Such Client" },
153         { JackLoadFailure,    "Load Failure" },
154         { JackInitFailure,    "Init Failure" },
155         { JackShmFailure,     "Shared Memory Access Failure" },
156         { JackVersionError,   "Version Mismatch" },
157 };
158
159 static const char *jack_status_to_str(jack_status_t status)
160 {
161         int i;
162
163         for (i = 0; i < ARRAY_LEN(jack_status_table); i++) {
164                 if (jack_status_table[i].status == status)
165                         return jack_status_table[i].str;
166         }
167
168         return "Unknown Error";
169 }
170
171 static void log_jack_status(const char *prefix, jack_status_t status)
172 {
173         struct ast_str *str = ast_str_alloca(512);
174         int i, first = 0;
175
176         for (i = 0; i < (sizeof(status) * 8); i++) {
177                 if (!(status & (1 << i)))
178                         continue;
179
180                 if (!first) {
181                         ast_str_set(&str, 0, "%s", jack_status_to_str((1 << i)));
182                         first = 1;
183                 } else
184                         ast_str_append(&str, 0, ", %s", jack_status_to_str((1 << i)));
185         }
186
187         ast_log(LOG_NOTICE, "%s: %s\n", prefix, ast_str_buffer(str));
188 }
189
190 static int alloc_resampler(struct jack_data *jack_data, int input)
191 {
192         double from_srate, to_srate, jack_srate;
193         void **resampler;
194         double *resample_factor;
195
196         if (input && jack_data->input_resampler)
197                 return 0;
198
199         if (!input && jack_data->output_resampler)
200                 return 0;
201
202         jack_srate = jack_get_sample_rate(jack_data->client);
203
204         /* XXX Hard coded 8 kHz */
205
206         to_srate = input ? 8000.0 : jack_srate;
207         from_srate = input ? jack_srate : 8000.0;
208
209         resample_factor = input ? &jack_data->input_resample_factor :
210                 &jack_data->output_resample_factor;
211
212         if (from_srate == to_srate) {
213                 /* Awesome!  The jack sample rate is the same as ours.
214                  * Resampling isn't needed. */
215                 *resample_factor = 1.0;
216                 return 0;
217         }
218
219         *resample_factor = to_srate / from_srate;
220
221         resampler = input ? &jack_data->input_resampler :
222                 &jack_data->output_resampler;
223
224         if (!(*resampler = resample_open(RESAMPLE_QUALITY,
225                 *resample_factor, *resample_factor))) {
226                 ast_log(LOG_ERROR, "Failed to open %s resampler\n",
227                         input ? "input" : "output");
228                 return -1;
229         }
230
231         return 0;
232 }
233
234 /*!
235  * \brief Handle jack input port
236  *
237  * Read nframes number of samples from the input buffer, resample it
238  * if necessary, and write it into the appropriate ringbuffer.
239  */
240 static void handle_input(void *buf, jack_nframes_t nframes,
241         struct jack_data *jack_data)
242 {
243         short s_buf[nframes];
244         float *in_buf = buf;
245         size_t res;
246         int i;
247         size_t write_len = sizeof(s_buf);
248
249         if (jack_data->input_resampler) {
250                 int total_in_buf_used = 0;
251                 int total_out_buf_used = 0;
252                 float f_buf[nframes + 1];
253
254                 memset(f_buf, 0, sizeof(f_buf));
255
256                 while (total_in_buf_used < nframes) {
257                         int in_buf_used;
258                         int out_buf_used;
259
260                         out_buf_used = resample_process(jack_data->input_resampler,
261                                 jack_data->input_resample_factor,
262                                 &in_buf[total_in_buf_used], nframes - total_in_buf_used,
263                                 0, &in_buf_used,
264                                 &f_buf[total_out_buf_used], ARRAY_LEN(f_buf) - total_out_buf_used);
265
266                         if (out_buf_used < 0)
267                                 break;
268
269                         total_out_buf_used += out_buf_used;
270                         total_in_buf_used += in_buf_used;
271
272                         if (total_out_buf_used == ARRAY_LEN(f_buf)) {
273                                 ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size, "
274                                         "nframes '%d', total_out_buf_used '%d'\n", nframes, total_out_buf_used);
275                                 break;
276                         }
277                 }
278
279                 for (i = 0; i < total_out_buf_used; i++)
280                         s_buf[i] = f_buf[i] * (SHRT_MAX / 1.0);
281
282                 write_len = total_out_buf_used * sizeof(int16_t);
283         } else {
284                 /* No resampling needed */
285
286                 for (i = 0; i < nframes; i++)
287                         s_buf[i] = in_buf[i] * (SHRT_MAX / 1.0);
288         }
289
290         res = jack_ringbuffer_write(jack_data->input_rb, (const char *) s_buf, write_len);
291         if (res != write_len) {
292                 ast_debug(2, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
293                         (int) sizeof(s_buf), (int) res);
294         }
295 }
296
297 /*!
298  * \brief Handle jack output port
299  *
300  * Read nframes number of samples from the ringbuffer and write it out to the
301  * output port buffer.
302  */
303 static void handle_output(void *buf, jack_nframes_t nframes,
304         struct jack_data *jack_data)
305 {
306         size_t res, len;
307
308         len = nframes * sizeof(float);
309
310         res = jack_ringbuffer_read(jack_data->output_rb, buf, len);
311
312         if (len != res) {
313                 ast_debug(2, "Wanted %d bytes to send to the output port, "
314                         "but only got %d\n", (int) len, (int) res);
315         }
316 }
317
318 static int jack_process(jack_nframes_t nframes, void *arg)
319 {
320         struct jack_data *jack_data = arg;
321         void *input_port_buf, *output_port_buf;
322
323         if (!jack_data->input_resample_factor)
324                 alloc_resampler(jack_data, 1);
325
326         input_port_buf = jack_port_get_buffer(jack_data->input_port, nframes);
327         handle_input(input_port_buf, nframes, jack_data);
328
329         output_port_buf = jack_port_get_buffer(jack_data->output_port, nframes);
330         handle_output(output_port_buf, nframes, jack_data);
331
332         return 0;
333 }
334
335 static void jack_shutdown(void *arg)
336 {
337         struct jack_data *jack_data = arg;
338
339         jack_data->stop = 1;
340 }
341
342 static struct jack_data *destroy_jack_data(struct jack_data *jack_data)
343 {
344         if (jack_data->input_port) {
345                 jack_port_unregister(jack_data->client, jack_data->input_port);
346                 jack_data->input_port = NULL;
347         }
348
349         if (jack_data->output_port) {
350                 jack_port_unregister(jack_data->client, jack_data->output_port);
351                 jack_data->output_port = NULL;
352         }
353
354         if (jack_data->client) {
355                 jack_client_close(jack_data->client);
356                 jack_data->client = NULL;
357         }
358
359         if (jack_data->input_rb) {
360                 jack_ringbuffer_free(jack_data->input_rb);
361                 jack_data->input_rb = NULL;
362         }
363
364         if (jack_data->output_rb) {
365                 jack_ringbuffer_free(jack_data->output_rb);
366                 jack_data->output_rb = NULL;
367         }
368
369         if (jack_data->output_resampler) {
370                 resample_close(jack_data->output_resampler);
371                 jack_data->output_resampler = NULL;
372         }
373
374         if (jack_data->input_resampler) {
375                 resample_close(jack_data->input_resampler);
376                 jack_data->input_resampler = NULL;
377         }
378
379         if (jack_data->has_audiohook)
380                 ast_audiohook_destroy(&jack_data->audiohook);
381
382         ast_string_field_free_memory(jack_data);
383
384         ast_free(jack_data);
385
386         return NULL;
387 }
388
389 static int init_jack_data(struct ast_channel *chan, struct jack_data *jack_data)
390 {
391         const char *client_name;
392         jack_status_t status = 0;
393         jack_options_t jack_options = JackNullOption;
394
395         if (!ast_strlen_zero(jack_data->client_name)) {
396                 client_name = jack_data->client_name;
397         } else {
398                 ast_channel_lock(chan);
399                 client_name = ast_strdupa(ast_channel_name(chan));
400                 ast_channel_unlock(chan);
401         }
402
403         if (!(jack_data->output_rb = jack_ringbuffer_create(RINGBUFFER_SIZE)))
404                 return -1;
405
406         if (!(jack_data->input_rb = jack_ringbuffer_create(RINGBUFFER_SIZE)))
407                 return -1;
408
409         if (jack_data->no_start_server)
410                 jack_options |= JackNoStartServer;
411
412         if (!ast_strlen_zero(jack_data->server_name)) {
413                 jack_options |= JackServerName;
414                 jack_data->client = jack_client_open(client_name, jack_options, &status,
415                         jack_data->server_name);
416         } else {
417                 jack_data->client = jack_client_open(client_name, jack_options, &status);
418         }
419
420         if (status)
421                 log_jack_status("Client Open Status", status);
422
423         if (!jack_data->client)
424                 return -1;
425
426         jack_data->input_port = jack_port_register(jack_data->client, "input",
427                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput | JackPortIsTerminal, 0);
428         if (!jack_data->input_port) {
429                 ast_log(LOG_ERROR, "Failed to create input port for jack port\n");
430                 return -1;
431         }
432
433         jack_data->output_port = jack_port_register(jack_data->client, "output",
434                 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput | JackPortIsTerminal, 0);
435         if (!jack_data->output_port) {
436                 ast_log(LOG_ERROR, "Failed to create output port for jack port\n");
437                 return -1;
438         }
439
440         if (jack_set_process_callback(jack_data->client, jack_process, jack_data)) {
441                 ast_log(LOG_ERROR, "Failed to register process callback with jack client\n");
442                 return -1;
443         }
444
445         jack_on_shutdown(jack_data->client, jack_shutdown, jack_data);
446
447         if (jack_activate(jack_data->client)) {
448                 ast_log(LOG_ERROR, "Unable to activate jack client\n");
449                 return -1;
450         }
451
452         while (!ast_strlen_zero(jack_data->connect_input_port)) {
453                 const char **ports;
454                 int i;
455
456                 ports = jack_get_ports(jack_data->client, jack_data->connect_input_port,
457                         NULL, JackPortIsInput);
458
459                 if (!ports) {
460                         ast_log(LOG_ERROR, "No input port matching '%s' was found\n",
461                                 jack_data->connect_input_port);
462                         break;
463                 }
464
465                 for (i = 0; ports[i]; i++) {
466                         ast_debug(1, "Found port '%s' that matched specified input port '%s'\n",
467                                 ports[i], jack_data->connect_input_port);
468                 }
469
470                 if (jack_connect(jack_data->client, jack_port_name(jack_data->output_port), ports[0])) {
471                         ast_log(LOG_ERROR, "Failed to connect '%s' to '%s'\n", ports[0],
472                                 jack_port_name(jack_data->output_port));
473                 } else {
474                         ast_debug(1, "Connected '%s' to '%s'\n", ports[0],
475                                 jack_port_name(jack_data->output_port));
476                 }
477
478                 free((void *) ports);
479
480                 break;
481         }
482
483         while (!ast_strlen_zero(jack_data->connect_output_port)) {
484                 const char **ports;
485                 int i;
486
487                 ports = jack_get_ports(jack_data->client, jack_data->connect_output_port,
488                         NULL, JackPortIsOutput);
489
490                 if (!ports) {
491                         ast_log(LOG_ERROR, "No output port matching '%s' was found\n",
492                                 jack_data->connect_output_port);
493                         break;
494                 }
495
496                 for (i = 0; ports[i]; i++) {
497                         ast_debug(1, "Found port '%s' that matched specified output port '%s'\n",
498                                 ports[i], jack_data->connect_output_port);
499                 }
500
501                 if (jack_connect(jack_data->client, ports[0], jack_port_name(jack_data->input_port))) {
502                         ast_log(LOG_ERROR, "Failed to connect '%s' to '%s'\n", ports[0],
503                                 jack_port_name(jack_data->input_port));
504                 } else {
505                         ast_debug(1, "Connected '%s' to '%s'\n", ports[0],
506                                 jack_port_name(jack_data->input_port));
507                 }
508
509                 free((void *) ports);
510
511                 break;
512         }
513
514         return 0;
515 }
516
517 static int queue_voice_frame(struct jack_data *jack_data, struct ast_frame *f)
518 {
519         float f_buf[f->samples * 8];
520         size_t f_buf_used = 0;
521         int i;
522         int16_t *s_buf = f->data.ptr;
523         size_t res;
524
525         memset(f_buf, 0, sizeof(f_buf));
526
527         if (!jack_data->output_resample_factor)
528                 alloc_resampler(jack_data, 0);
529
530         if (jack_data->output_resampler) {
531                 float in_buf[f->samples];
532                 int total_in_buf_used = 0;
533                 int total_out_buf_used = 0;
534
535                 memset(in_buf, 0, sizeof(in_buf));
536
537                 for (i = 0; i < f->samples; i++)
538                         in_buf[i] = s_buf[i] * (1.0 / SHRT_MAX);
539
540                 while (total_in_buf_used < ARRAY_LEN(in_buf)) {
541                         int in_buf_used;
542                         int out_buf_used;
543
544                         out_buf_used = resample_process(jack_data->output_resampler,
545                                 jack_data->output_resample_factor,
546                                 &in_buf[total_in_buf_used], ARRAY_LEN(in_buf) - total_in_buf_used,
547                                 0, &in_buf_used,
548                                 &f_buf[total_out_buf_used], ARRAY_LEN(f_buf) - total_out_buf_used);
549
550                         if (out_buf_used < 0)
551                                 break;
552
553                         total_out_buf_used += out_buf_used;
554                         total_in_buf_used += in_buf_used;
555
556                         if (total_out_buf_used == ARRAY_LEN(f_buf)) {
557                                 ast_log(LOG_ERROR, "Output buffer filled ... need to increase its size\n");
558                                 break;
559                         }
560                 }
561
562                 f_buf_used = total_out_buf_used;
563                 if (f_buf_used > ARRAY_LEN(f_buf))
564                         f_buf_used = ARRAY_LEN(f_buf);
565         } else {
566                 /* No resampling needed */
567
568                 for (i = 0; i < f->samples; i++)
569                         f_buf[i] = s_buf[i] * (1.0 / SHRT_MAX);
570
571                 f_buf_used = f->samples;
572         }
573
574         res = jack_ringbuffer_write(jack_data->output_rb, (const char *) f_buf, f_buf_used * sizeof(float));
575         if (res != (f_buf_used * sizeof(float))) {
576                 ast_debug(2, "Tried to write %d bytes to the ringbuffer, but only wrote %d\n",
577                         (int) (f_buf_used * sizeof(float)), (int) res);
578         }
579
580         return 0;
581 }
582
583 /*!
584  * \brief handle jack audio
585  *
586  * \param[in]  chan The Asterisk channel to write the frames to if no output frame
587  *             is provided.
588  * \param[in]  jack_data This is the jack_data struct that contains the input
589  *             ringbuffer that audio will be read from.
590  * \param[out] out_frame If this argument is non-NULL, then assuming there is
591  *             enough data avilable in the ringbuffer, the audio in this frame
592  *             will get replaced with audio from the input buffer.  If there is
593  *             not enough data available to read at this time, then the frame
594  *             data gets zeroed out.
595  *
596  * Read data from the input ringbuffer, which is the properly resampled audio
597  * that was read from the jack input port.  Write it to the channel in 20 ms frames,
598  * or fill up an output frame instead if one is provided.
599  *
600  * \return Nothing.
601  */
602 static void handle_jack_audio(struct ast_channel *chan, struct jack_data *jack_data,
603         struct ast_frame *out_frame)
604 {
605         short buf[160];
606         struct ast_frame f = {
607                 .frametype = AST_FRAME_VOICE,
608                 .src = "JACK",
609                 .data.ptr = buf,
610                 .datalen = sizeof(buf),
611                 .samples = ARRAY_LEN(buf),
612         };
613         ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
614
615         for (;;) {
616                 size_t res, read_len;
617                 char *read_buf;
618
619                 read_len = out_frame ? out_frame->datalen : sizeof(buf);
620                 read_buf = out_frame ? out_frame->data.ptr : buf;
621
622                 res = jack_ringbuffer_read_space(jack_data->input_rb);
623
624                 if (res < read_len) {
625                         /* Not enough data ready for another frame, move on ... */
626                         if (out_frame) {
627                                 ast_debug(1, "Sending an empty frame for the JACK_HOOK\n");
628                                 memset(out_frame->data.ptr, 0, out_frame->datalen);
629                         }
630                         break;
631                 }
632
633                 res = jack_ringbuffer_read(jack_data->input_rb, (char *) read_buf, read_len);
634
635                 if (res < read_len) {
636                         ast_log(LOG_ERROR, "Error reading from ringbuffer, even though it said there was enough data\n");
637                         break;
638                 }
639
640                 if (out_frame) {
641                         /* If an output frame was provided, then we just want to fill up the
642                          * buffer in that frame and return. */
643                         break;
644                 }
645
646                 ast_write(chan, &f);
647         }
648 }
649
650 enum {
651         OPT_SERVER_NAME =    (1 << 0),
652         OPT_INPUT_PORT =     (1 << 1),
653         OPT_OUTPUT_PORT =    (1 << 2),
654         OPT_NOSTART_SERVER = (1 << 3),
655         OPT_CLIENT_NAME =    (1 << 4),
656 };
657
658 enum {
659         OPT_ARG_SERVER_NAME,
660         OPT_ARG_INPUT_PORT,
661         OPT_ARG_OUTPUT_PORT,
662         OPT_ARG_CLIENT_NAME,
663
664         /* Must be the last element */
665         OPT_ARG_ARRAY_SIZE,
666 };
667
668 AST_APP_OPTIONS(jack_exec_options, BEGIN_OPTIONS
669         AST_APP_OPTION_ARG('s', OPT_SERVER_NAME, OPT_ARG_SERVER_NAME),
670         AST_APP_OPTION_ARG('i', OPT_INPUT_PORT, OPT_ARG_INPUT_PORT),
671         AST_APP_OPTION_ARG('o', OPT_OUTPUT_PORT, OPT_ARG_OUTPUT_PORT),
672         AST_APP_OPTION('n', OPT_NOSTART_SERVER),
673         AST_APP_OPTION_ARG('c', OPT_CLIENT_NAME, OPT_ARG_CLIENT_NAME),
674 END_OPTIONS );
675
676 static struct jack_data *jack_data_alloc(void)
677 {
678         struct jack_data *jack_data;
679
680         if (!(jack_data = ast_calloc_with_stringfields(1, struct jack_data, 32))) {
681                 return NULL;
682         }
683
684         return jack_data;
685 }
686
687 /*!
688  * \note This must be done before calling init_jack_data().
689  */
690 static int handle_options(struct jack_data *jack_data, const char *__options_str)
691 {
692         struct ast_flags options = { 0, };
693         char *option_args[OPT_ARG_ARRAY_SIZE];
694         char *options_str;
695
696         options_str = ast_strdupa(__options_str);
697
698         ast_app_parse_options(jack_exec_options, &options, option_args, options_str);
699
700         if (ast_test_flag(&options, OPT_SERVER_NAME)) {
701                 if (!ast_strlen_zero(option_args[OPT_ARG_SERVER_NAME]))
702                         ast_string_field_set(jack_data, server_name, option_args[OPT_ARG_SERVER_NAME]);
703                 else {
704                         ast_log(LOG_ERROR, "A server name must be provided with the s() option\n");
705                         return -1;
706                 }
707         }
708
709         if (ast_test_flag(&options, OPT_CLIENT_NAME)) {
710                 if (!ast_strlen_zero(option_args[OPT_ARG_CLIENT_NAME]))
711                         ast_string_field_set(jack_data, client_name, option_args[OPT_ARG_CLIENT_NAME]);
712                 else {
713                         ast_log(LOG_ERROR, "A client name must be provided with the c() option\n");
714                         return -1;
715                 }
716         }
717
718         if (ast_test_flag(&options, OPT_INPUT_PORT)) {
719                 if (!ast_strlen_zero(option_args[OPT_ARG_INPUT_PORT]))
720                         ast_string_field_set(jack_data, connect_input_port, option_args[OPT_ARG_INPUT_PORT]);
721                 else {
722                         ast_log(LOG_ERROR, "A name must be provided with the i() option\n");
723                         return -1;
724                 }
725         }
726
727         if (ast_test_flag(&options, OPT_OUTPUT_PORT)) {
728                 if (!ast_strlen_zero(option_args[OPT_ARG_OUTPUT_PORT]))
729                         ast_string_field_set(jack_data, connect_output_port, option_args[OPT_ARG_OUTPUT_PORT]);
730                 else {
731                         ast_log(LOG_ERROR, "A name must be provided with the o() option\n");
732                         return -1;
733                 }
734         }
735
736         jack_data->no_start_server = ast_test_flag(&options, OPT_NOSTART_SERVER) ? 1 : 0;
737
738         return 0;
739 }
740
741 static int jack_exec(struct ast_channel *chan, const char *data)
742 {
743         struct jack_data *jack_data;
744
745         if (!(jack_data = jack_data_alloc()))
746                 return -1;
747
748         if (!ast_strlen_zero(data) && handle_options(jack_data, data)) {
749                 destroy_jack_data(jack_data);
750                 return -1;
751         }
752
753         if (init_jack_data(chan, jack_data)) {
754                 destroy_jack_data(jack_data);
755                 return -1;
756         }
757
758         if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
759                 destroy_jack_data(jack_data);
760                 return -1;
761         }
762
763         if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
764                 destroy_jack_data(jack_data);
765                 return -1;
766         }
767
768         while (!jack_data->stop) {
769                 struct ast_frame *f;
770
771                 if (ast_waitfor(chan, -1) < 0) {
772                         break;
773                 }
774
775                 f = ast_read(chan);
776                 if (!f) {
777                         jack_data->stop = 1;
778                         continue;
779                 }
780
781                 switch (f->frametype) {
782                 case AST_FRAME_CONTROL:
783                         if (f->subclass.integer == AST_CONTROL_HANGUP)
784                                 jack_data->stop = 1;
785                         break;
786                 case AST_FRAME_VOICE:
787                         queue_voice_frame(jack_data, f);
788                 default:
789                         break;
790                 }
791
792                 ast_frfree(f);
793
794                 handle_jack_audio(chan, jack_data, NULL);
795         }
796
797         jack_data = destroy_jack_data(jack_data);
798
799         return 0;
800 }
801
802 static void jack_hook_ds_destroy(void *data)
803 {
804         struct jack_data *jack_data = data;
805
806         destroy_jack_data(jack_data);
807 }
808
809 static const struct ast_datastore_info jack_hook_ds_info = {
810         .type = "JACK_HOOK",
811         .destroy = jack_hook_ds_destroy,
812 };
813
814 static int jack_hook_callback(struct ast_audiohook *audiohook, struct ast_channel *chan,
815         struct ast_frame *frame, enum ast_audiohook_direction direction)
816 {
817         struct ast_datastore *datastore;
818         struct jack_data *jack_data;
819
820         if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE)
821                 return 0;
822
823         if (direction != AST_AUDIOHOOK_DIRECTION_READ)
824                 return 0;
825
826         if (frame->frametype != AST_FRAME_VOICE)
827                 return 0;
828
829         if (frame->subclass.format.id != AST_FORMAT_SLINEAR) {
830                 ast_log(LOG_WARNING, "Expected frame in SLINEAR for the audiohook, but got format %s\n",
831                         ast_getformatname(&frame->subclass.format));
832                 return 0;
833         }
834
835         ast_channel_lock(chan);
836
837         if (!(datastore = ast_channel_datastore_find(chan, &jack_hook_ds_info, NULL))) {
838                 ast_log(LOG_ERROR, "JACK_HOOK datastore not found for '%s'\n", ast_channel_name(chan));
839                 ast_channel_unlock(chan);
840                 return -1;
841         }
842
843         jack_data = datastore->data;
844
845         queue_voice_frame(jack_data, frame);
846
847         handle_jack_audio(chan, jack_data, frame);
848
849         ast_channel_unlock(chan);
850
851         return 0;
852 }
853
854 static int enable_jack_hook(struct ast_channel *chan, char *data)
855 {
856         struct ast_datastore *datastore;
857         struct jack_data *jack_data = NULL;
858         AST_DECLARE_APP_ARGS(args,
859                 AST_APP_ARG(mode);
860                 AST_APP_ARG(options);
861         );
862
863         AST_STANDARD_APP_ARGS(args, data);
864
865         ast_channel_lock(chan);
866
867         if ((datastore = ast_channel_datastore_find(chan, &jack_hook_ds_info, NULL))) {
868                 ast_log(LOG_ERROR, "JACK_HOOK already enabled for '%s'\n", ast_channel_name(chan));
869                 goto return_error;
870         }
871
872         if (ast_strlen_zero(args.mode) || strcasecmp(args.mode, "manipulate")) {
873                 ast_log(LOG_ERROR, "'%s' is not a supported mode.  Only manipulate is supported.\n",
874                         S_OR(args.mode, "<none>"));
875                 goto return_error;
876         }
877
878         if (!(jack_data = jack_data_alloc()))
879                 goto return_error;
880
881         if (!ast_strlen_zero(args.options) && handle_options(jack_data, args.options))
882                 goto return_error;
883
884         if (init_jack_data(chan, jack_data))
885                 goto return_error;
886
887         if (!(datastore = ast_datastore_alloc(&jack_hook_ds_info, NULL)))
888                 goto return_error;
889
890         jack_data->has_audiohook = 1;
891         ast_audiohook_init(&jack_data->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "JACK_HOOK", 0);
892         jack_data->audiohook.manipulate_callback = jack_hook_callback;
893
894         datastore->data = jack_data;
895
896         if (ast_audiohook_attach(chan, &jack_data->audiohook))
897                 goto return_error;
898
899         if (ast_channel_datastore_add(chan, datastore))
900                 goto return_error;
901
902         ast_channel_unlock(chan);
903
904         return 0;
905
906 return_error:
907         ast_channel_unlock(chan);
908
909         if (jack_data) {
910                 destroy_jack_data(jack_data);
911         }
912
913         if (datastore) {
914                 datastore->data = NULL;
915                 ast_datastore_free(datastore);
916         }
917
918         return -1;
919 }
920
921 static int disable_jack_hook(struct ast_channel *chan)
922 {
923         struct ast_datastore *datastore;
924         struct jack_data *jack_data;
925
926         ast_channel_lock(chan);
927
928         if (!(datastore = ast_channel_datastore_find(chan, &jack_hook_ds_info, NULL))) {
929                 ast_channel_unlock(chan);
930                 ast_log(LOG_WARNING, "No JACK_HOOK found to disable\n");
931                 return -1;
932         }
933
934         ast_channel_datastore_remove(chan, datastore);
935
936         jack_data = datastore->data;
937         ast_audiohook_detach(&jack_data->audiohook);
938
939         /* Keep the channel locked while we destroy the datastore, so that we can
940          * ensure that all of the jack stuff is stopped just in case another frame
941          * tries to come through the audiohook callback. */
942         ast_datastore_free(datastore);
943
944         ast_channel_unlock(chan);
945
946         return 0;
947 }
948
949 static int jack_hook_write(struct ast_channel *chan, const char *cmd, char *data,
950         const char *value)
951 {
952         int res;
953
954         if (!strcasecmp(value, "on"))
955                 res = enable_jack_hook(chan, data);
956         else if (!strcasecmp(value, "off"))
957                 res = disable_jack_hook(chan);
958         else {
959                 ast_log(LOG_ERROR, "'%s' is not a valid value for JACK_HOOK()\n", value);
960                 res = -1;
961         }
962
963         return res;
964 }
965
966 static struct ast_custom_function jack_hook_function = {
967         .name = "JACK_HOOK",
968         .synopsis = "Enable a jack hook on a channel",
969         .syntax = "JACK_HOOK(<mode>,[options])",
970         .desc =
971         "   The JACK_HOOK allows turning on or off jack connectivity to this channel.\n"
972         "When the JACK_HOOK is turned on, jack ports will get created that allow\n"
973         "access to the audio stream for this channel.  The mode specifies which mode\n"
974         "this hook should run in.  A mode must be specified when turning the JACK_HOOK.\n"
975         "on.  However, all arguments are optional when turning it off.\n"
976         "\n"
977         "   Valid modes are:\n"
978 #if 0
979         /* XXX TODO */
980         "    spy -        Create a read-only audio hook.  Only an output jack port will\n"
981         "                 get created.\n"
982         "    whisper -    Create a write-only audio hook.  Only an input jack port will\n"
983         "                 get created.\n"
984 #endif
985         "    manipulate - Create a read/write audio hook.  Both an input and an output\n"
986         "                 jack port will get created.  Audio from the channel will be\n"
987         "                 sent out the output port and will be replaced by the audio\n"
988         "                 coming in on the input port as it gets passed on.\n"
989         "\n"
990         "   Valid options are:\n"
991         COMMON_OPTIONS
992         "\n"
993         " Examples:\n"
994         "   To turn on the JACK_HOOK,\n"
995         "     Set(JACK_HOOK(manipulate,i(pure_data_0:input0)o(pure_data_0:output0))=on)\n"
996         "   To turn off the JACK_HOOK,\n"
997         "     Set(JACK_HOOK()=off)\n"
998         "",
999         .write = jack_hook_write,
1000 };
1001
1002 static int unload_module(void)
1003 {
1004         int res;
1005
1006         res = ast_unregister_application(jack_app);
1007         res |= ast_custom_function_unregister(&jack_hook_function);
1008
1009         return res;
1010 }
1011
1012 static int load_module(void)
1013 {
1014         if (ast_register_application_xml(jack_app, jack_exec)) {
1015                 return AST_MODULE_LOAD_DECLINE;
1016         }
1017
1018         if (ast_custom_function_register(&jack_hook_function)) {
1019                 ast_unregister_application(jack_app);
1020                 return AST_MODULE_LOAD_DECLINE;
1021         }
1022
1023         return AST_MODULE_LOAD_SUCCESS;
1024 }
1025
1026 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "JACK Interface");