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