Merge the main set of changes from team/russell/chan_console.
[asterisk/asterisk.git] / channels / chan_console.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2006 - 2007, Digium, Inc.
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 Cross-platform console channel driver 
22  *
23  * \author Russell Bryant <russell@digium.com>
24  *
25  * \note Some of the code in this file came from chan_oss and chan_alsa.
26  *       chan_oss,  Mark Spencer <markster@digium.com>
27  *       chan_oss,  Luigi Rizzo
28  *       chan_alsa, Matthew Fredrickson <creslin@digium.com>
29  * 
30  * \ingroup channel_drivers
31  *
32  * \note Since this works with any audio system that libportaudio supports,
33  * including ALSA and OSS, this may someday deprecate chan_alsa and chan_oss.
34  * However, before that can be done, it needs to *at least* have all of the
35  * features that these other channel drivers have.  The features implemented
36  * in at least one of the other console channel drivers that are not yet
37  * implemented here are:
38  *
39  * - Multiple device support
40  *   - with "active" CLI command
41  * - Set Auto-answer from the dialplan
42  * - transfer CLI command
43  * - boost CLI command and .conf option
44  * - console_video support
45  */
46
47 /*** MODULEINFO
48         <depend>portaudio</depend>
49  ***/
50
51 #include "asterisk.h"
52
53 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
54
55 #include <sys/signal.h>  /* SIGURG */
56
57 #include <portaudio.h>
58
59 #include "asterisk/module.h"
60 #include "asterisk/channel.h"
61 #include "asterisk/pbx.h"
62 #include "asterisk/causes.h"
63 #include "asterisk/cli.h"
64 #include "asterisk/musiconhold.h"
65 #include "asterisk/callerid.h"
66
67 /*! 
68  * \brief The sample rate to request from PortAudio 
69  *
70  * \note This should be changed to 16000 once there is a translator for going
71  *       between SLINEAR and SLINEAR16.  Making it a configuration parameter
72  *       would be even better, but 16 kHz should be the default.
73  *
74  * \note If this changes, NUM_SAMPLES will need to change, as well.
75  */
76 #define SAMPLE_RATE      8000
77
78 /*! 
79  * \brief The number of samples to configure the portaudio stream for
80  *
81  * 160 samples (20 ms) is the most common frame size in Asterisk.  So, the code
82  * in this module reads 160 sample frames from the portaudio stream and queues
83  * them up on the Asterisk channel.  Frames of any sizes can be written to a
84  * portaudio stream, but the portaudio documentation does say that for high
85  * performance applications, the data should be written to Pa_WriteStream in
86  * the same size as what is used to initialize the stream.
87  *
88  * \note This will need to be dynamic once the sample rate can be something
89  *       other than 8 kHz.
90  */
91 #define NUM_SAMPLES      160
92
93 /*! \brief Mono Input */
94 #define INPUT_CHANNELS   1
95
96 /*! \brief Mono Output */
97 #define OUTPUT_CHANNELS  1
98
99 /*! 
100  * \brief Maximum text message length
101  * \note This should be changed if there is a common definition somewhere
102  *       that defines the maximum length of a text message.
103  */
104 #define TEXT_SIZE       256
105
106 #ifndef MIN
107 #define MIN(a,b) ((a) < (b) ? (a) : (b))
108 #endif
109 #ifndef MAX
110 #define MAX(a,b) ((a) > (b) ? (a) : (b))
111 #endif
112
113 /*! \brief Dance, Kirby, Dance! @{ */
114 #define V_BEGIN " --- <(\"<) --- "
115 #define V_END   " --- (>\")> ---\n"
116 /*! @} */
117
118 static const char config_file[] = "console.conf";
119
120 /*!
121  * \brief Console pvt structure
122  *
123  * Currently, this is a singleton object.  However, multiple instances will be
124  * needed when this module is updated for multiple device support.
125  */
126 static struct console_pvt {
127         AST_DECLARE_STRING_FIELDS(
128                 /*! Name of the device */
129                 AST_STRING_FIELD(name);
130                 /*! Default context for outgoing calls */
131                 AST_STRING_FIELD(context);
132                 /*! Default extension for outgoing calls */
133                 AST_STRING_FIELD(exten);
134                 /*! Default CallerID number */
135                 AST_STRING_FIELD(cid_num);
136                 /*! Default CallerID name */
137                 AST_STRING_FIELD(cid_name);
138                 /*! Default MOH class to listen to, if:
139                  *    - No MOH class set on the channel
140                  *    - Peer channel putting this device on hold did not suggest a class */
141                 AST_STRING_FIELD(mohinterpret);
142                 /*! Default language */
143                 AST_STRING_FIELD(language);
144         );
145         /*! Current channel for this device */
146         struct ast_channel *owner;
147         /*! Current PortAudio stream for this device */
148         PaStream *stream;
149         /*! A frame for preparing to queue on to the channel */
150         struct ast_frame fr;
151         /*! Running = 1, Not running = 0 */
152         unsigned int streamstate:1;
153         /*! On-hook = 0, Off-hook = 1 */
154         unsigned int hookstate:1;
155         /*! Unmuted = 0, Muted = 1 */
156         unsigned int muted:1;
157         /*! Automatically answer incoming calls */
158         unsigned int autoanswer:1;
159         /*! Ignore context in the console dial CLI command */
160         unsigned int overridecontext:1;
161         /*! Lock to protect data in this struct */
162         ast_mutex_t __lock;
163         /*! ID for the stream monitor thread */
164         pthread_t thread;
165 } console_pvt = {
166         .__lock = AST_MUTEX_INIT_VALUE,
167         .thread = AST_PTHREADT_NULL,
168 };
169
170 /*! 
171  * \brief Global jitterbuffer configuration 
172  *
173  * \note Disabled by default.
174  */
175 static struct ast_jb_conf default_jbconf = {
176         .flags = 0,
177         .max_size = -1,
178         .resync_threshold = -1,
179         .impl = ""
180 };
181 static struct ast_jb_conf global_jbconf;
182
183 /*! Channel Technology Callbacks @{ */
184 static struct ast_channel *console_request(const char *type, int format, 
185         void *data, int *cause);
186 static int console_digit_begin(struct ast_channel *c, char digit);
187 static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration);
188 static int console_text(struct ast_channel *c, const char *text);
189 static int console_hangup(struct ast_channel *c);
190 static int console_answer(struct ast_channel *c);
191 static struct ast_frame *console_read(struct ast_channel *chan);
192 static int console_call(struct ast_channel *c, char *dest, int timeout);
193 static int console_write(struct ast_channel *chan, struct ast_frame *f);
194 static int console_indicate(struct ast_channel *chan, int cond, 
195         const void *data, size_t datalen);
196 static int console_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
197 /*! @} */
198
199 /*!
200  * \brief Formats natively supported by this module.
201  *
202  * \note Once 16 kHz is supported, AST_FORMAT_SLINEAR16 needs to be added.
203  */
204 #define SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR )
205
206 static const struct ast_channel_tech console_tech = {
207         .type = "Console",
208         .description = "Console Channel Driver",
209         .capabilities = SUPPORTED_FORMATS,
210         .requester = console_request,
211         .send_digit_begin = console_digit_begin,
212         .send_digit_end = console_digit_end,
213         .send_text = console_text,
214         .hangup = console_hangup,
215         .answer = console_answer,
216         .read = console_read,
217         .call = console_call,
218         .write = console_write,
219         .indicate = console_indicate,
220         .fixup = console_fixup,
221 };
222
223 /*! \brief lock a console_pvt struct */
224 #define console_pvt_lock(pvt) ast_mutex_lock(&(pvt)->__lock)
225
226 /*! \brief unlock a console_pvt struct */
227 #define console_pvt_unlock(pvt) ast_mutex_unlock(&(pvt)->__lock)
228
229 /*!
230  * \brief Stream monitor thread 
231  *
232  * \arg data A pointer to the console_pvt structure that contains the portaudio
233  *      stream that needs to be monitored.
234  *
235  * This function runs in its own thread to monitor data coming in from a
236  * portaudio stream.  When enough data is available, it is queued up to
237  * be read from the Asterisk channel.
238  */
239 static void *stream_monitor(void *data)
240 {
241         struct console_pvt *pvt = data;
242         char buf[NUM_SAMPLES * sizeof(int16_t)];
243         PaError res;
244         struct ast_frame f = {
245                 .frametype = AST_FRAME_VOICE,
246                 .subclass = AST_FORMAT_SLINEAR,
247                 .src = "console_stream_monitor",
248                 .data = buf,
249                 .datalen = sizeof(buf),
250                 .samples = sizeof(buf) / sizeof(int16_t),
251         };
252
253         for (;;) {
254                 pthread_testcancel();
255                 res = Pa_ReadStream(pvt->stream, buf, sizeof(buf) / sizeof(int16_t));
256                 pthread_testcancel();
257
258                 if (res == paNoError)
259                         ast_queue_frame(pvt->owner, &f);
260         }
261
262         return NULL;
263 }
264
265 static int start_stream(struct console_pvt *pvt)
266 {
267         PaError res;
268         int ret_val = 0;
269
270         console_pvt_lock(pvt);
271
272         if (pvt->streamstate)
273                 goto return_unlock;
274
275         pvt->streamstate = 1;
276         ast_debug(1, "Starting stream\n");
277
278         res = Pa_OpenDefaultStream(&pvt->stream, INPUT_CHANNELS, OUTPUT_CHANNELS, 
279                 paInt16, SAMPLE_RATE, NUM_SAMPLES, NULL, NULL);
280         if (res != paNoError) {
281                 ast_log(LOG_WARNING, "Failed to open default audio device - (%d) %s\n",
282                         res, Pa_GetErrorText(res));
283                 ret_val = -1;
284                 goto return_unlock;
285         }
286
287         res = Pa_StartStream(pvt->stream);
288         if (res != paNoError) {
289                 ast_log(LOG_WARNING, "Failed to start stream - (%d) %s\n",
290                         res, Pa_GetErrorText(res));
291                 ret_val = -1;
292                 goto return_unlock;
293         }
294
295         if (ast_pthread_create_background(&pvt->thread, NULL, stream_monitor, pvt)) {
296                 ast_log(LOG_ERROR, "Failed to start stream monitor thread\n");
297                 ret_val = -1;
298         }
299
300 return_unlock:
301         console_pvt_unlock(pvt);
302
303         return ret_val;
304 }
305
306 static int stop_stream(struct console_pvt *pvt)
307 {
308         if (!pvt->streamstate)
309                 return 0;
310
311         pthread_cancel(pvt->thread);
312         pthread_kill(pvt->thread, SIGURG);
313         pthread_join(pvt->thread, NULL);
314
315         console_pvt_lock(pvt);
316         Pa_AbortStream(pvt->stream);
317         Pa_CloseStream(pvt->stream);
318         pvt->stream = NULL;
319         pvt->streamstate = 0;
320         console_pvt_unlock(pvt);
321
322         return 0;
323 }
324
325 /*!
326  * \note Called with the pvt struct locked
327  */
328 static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state)
329 {
330         struct ast_channel *chan;
331
332         if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL, 
333                 ext, ctx, 0, "Console/%s", pvt->name))) {
334                 return NULL;
335         }
336
337         chan->tech = &console_tech;
338         chan->nativeformats = AST_FORMAT_SLINEAR;
339         chan->readformat = AST_FORMAT_SLINEAR;
340         chan->writeformat = AST_FORMAT_SLINEAR;
341         chan->tech_pvt = pvt;
342
343         pvt->owner = chan;
344
345         if (!ast_strlen_zero(pvt->language))
346                 ast_string_field_set(chan, language, pvt->language);
347
348         ast_jb_configure(chan, &global_jbconf);
349
350         if (state != AST_STATE_DOWN) {
351                 if (ast_pbx_start(chan)) {
352                         chan->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
353                         ast_hangup(chan);
354                         chan = NULL;
355                 } else
356                         start_stream(pvt);
357         }
358
359         return chan;
360 }
361
362 static struct ast_channel *console_request(const char *type, int format, void *data, int *cause)
363 {
364         int oldformat = format;
365         struct ast_channel *chan;
366         struct console_pvt *pvt = &console_pvt;
367
368         format &= SUPPORTED_FORMATS;
369         if (!format) {
370                 ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%d'\n", oldformat);
371                 return NULL;
372         }
373
374         if (pvt->owner) {
375                 ast_log(LOG_NOTICE, "Console channel already active!\n");
376                 *cause = AST_CAUSE_BUSY;
377                 return NULL;
378         }
379
380         console_pvt_lock(pvt);
381         chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN);
382         console_pvt_unlock(pvt);
383
384         if (!chan)
385                 ast_log(LOG_WARNING, "Unable to create new Console channel!\n");
386
387         return chan;
388 }
389
390 static int console_digit_begin(struct ast_channel *c, char digit)
391 {
392         ast_verb(1, V_BEGIN "Console Received Beginning of Digit %c" V_END, digit);
393
394         return -1; /* non-zero to request inband audio */
395 }
396
397 static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration)
398 {
399         ast_verb(1, V_BEGIN "Console Received End of Digit %c (duration %u)" V_END, 
400                 digit, duration);
401
402         return -1; /* non-zero to request inband audio */
403 }
404
405 static int console_text(struct ast_channel *c, const char *text)
406 {
407         ast_verb(1, V_BEGIN "Console Received Text '%s'" V_END, text);
408
409         return 0;
410 }
411
412 static int console_hangup(struct ast_channel *c)
413 {
414         struct console_pvt *pvt = &console_pvt;
415
416         ast_verb(1, V_BEGIN "Hangup on Console" V_END);
417
418         pvt->hookstate = 0;
419         c->tech_pvt = NULL;
420         pvt->owner = NULL;
421
422         stop_stream(pvt);
423
424         return 0;
425 }
426
427 static int console_answer(struct ast_channel *c)
428 {
429         struct console_pvt *pvt = &console_pvt;
430
431         ast_verb(1, V_BEGIN "Call from Console has been Answered" V_END);
432
433         ast_setstate(c, AST_STATE_UP);
434
435         return start_stream(pvt);
436 }
437
438 /*
439  * \brief Implementation of the ast_channel_tech read() callback
440  *
441  * Calling this function is harmless.  However, if it does get called, it
442  * is an indication that something weird happened that really shouldn't
443  * have and is worth looking into.
444  * 
445  * Why should this function not get called?  Well, let me explain.  There are
446  * a couple of ways to pass on audio that has come from this channel.  The way
447  * that this channel driver uses is that once the audio is available, it is
448  * wrapped in an ast_frame and queued onto the channel using ast_queue_frame().
449  *
450  * The other method would be signalling to the core that there is audio waiting,
451  * and that it needs to call the channel's read() callback to get it.  The way
452  * the channel gets signalled is that one or more file descriptors are placed
453  * in the fds array on the ast_channel which the core will poll() on.  When the
454  * fd indicates that input is available, the read() callback is called.  This
455  * is especially useful when there is a dedicated file descriptor where the
456  * audio is read from.  An example would be the socket for an RTP stream.
457  */
458 static struct ast_frame *console_read(struct ast_channel *chan)
459 {
460         ast_debug(1, "I should not be called ...\n");
461
462         return &ast_null_frame;
463 }
464
465 static int console_call(struct ast_channel *c, char *dest, int timeout)
466 {
467         struct ast_frame f = { 0, };
468         struct console_pvt *pvt = &console_pvt;
469
470         ast_verb(1, V_BEGIN "Call to device '%s' on console from '%s' <%s>" V_END,
471                 dest, c->cid.cid_name, c->cid.cid_num);
472
473         console_pvt_lock(pvt);
474
475         if (pvt->autoanswer) {
476                 ast_verb(1, V_BEGIN "Auto-answered" V_END);
477                 pvt->hookstate = 1;
478                 f.frametype = AST_FRAME_CONTROL;
479                 f.subclass = AST_CONTROL_ANSWER;
480         } else {
481                 ast_verb(1, V_BEGIN "Type 'answer' to answer, or use 'autoanswer' "
482                                 "for future calls" V_END);
483                 f.frametype = AST_FRAME_CONTROL;
484                 f.subclass = AST_CONTROL_RINGING;
485         }
486
487         console_pvt_unlock(pvt);
488
489         ast_queue_frame(c, &f);
490
491         return start_stream(pvt);
492 }
493
494 static int console_write(struct ast_channel *chan, struct ast_frame *f)
495 {
496         struct console_pvt *pvt = &console_pvt;
497
498         Pa_WriteStream(pvt->stream, f->data, f->samples);
499
500         return 0;
501 }
502
503 static int console_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen)
504 {
505         struct console_pvt *pvt = chan->tech_pvt;
506         int res = 0;
507
508         switch (cond) {
509         case AST_CONTROL_BUSY:
510         case AST_CONTROL_CONGESTION:
511         case AST_CONTROL_RINGING:
512                 res = -1;  /* Ask for inband indications */
513                 break;
514         case AST_CONTROL_PROGRESS:
515         case AST_CONTROL_PROCEEDING:
516         case AST_CONTROL_VIDUPDATE:
517         case -1:
518                 break;
519         case AST_CONTROL_HOLD:
520                 ast_verb(1, V_BEGIN "Console Has Been Placed on Hold" V_END);
521                 ast_moh_start(chan, data, pvt->mohinterpret);
522                 break;
523         case AST_CONTROL_UNHOLD:
524                 ast_verb(1, V_BEGIN "Console Has Been Retrieved from Hold" V_END);
525                 ast_moh_stop(chan);
526                 break;
527         default:
528                 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", 
529                         cond, chan->name);
530                 /* The core will play inband indications for us if appropriate */
531                 res = -1;
532         }
533
534         return res;
535 }
536
537 static int console_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
538 {
539         struct console_pvt *pvt = &console_pvt;
540
541         pvt->owner = newchan;
542
543         return 0;
544 }
545
546 /*!
547  * split a string in extension-context, returns pointers to malloc'ed
548  * strings.
549  * If we do not have 'overridecontext' then the last @ is considered as
550  * a context separator, and the context is overridden.
551  * This is usually not very necessary as you can play with the dialplan,
552  * and it is nice not to need it because you have '@' in SIP addresses.
553  * Return value is the buffer address.
554  *
555  * \note came from chan_oss
556  */
557 static char *ast_ext_ctx(struct console_pvt *pvt, const char *src, char **ext, char **ctx)
558 {
559         if (ext == NULL || ctx == NULL)
560                 return NULL;                    /* error */
561
562         *ext = *ctx = NULL;
563
564         if (src && *src != '\0')
565                 *ext = ast_strdup(src);
566
567         if (*ext == NULL)
568                 return NULL;
569
570         if (!pvt->overridecontext) {
571                 /* parse from the right */
572                 *ctx = strrchr(*ext, '@');
573                 if (*ctx)
574                         *(*ctx)++ = '\0';
575         }
576
577         return *ext;
578 }
579
580 static char *cli_console_autoanswer(struct ast_cli_entry *e, int cmd, 
581         struct ast_cli_args *a)
582 {
583         struct console_pvt *pvt = &console_pvt;
584
585         switch (cmd) {
586         case CLI_INIT:
587                 e->command = "console set autoanswer [on|off]";
588                 e->usage =
589                         "Usage: console set autoanswer [on|off]\n"
590                         "       Enables or disables autoanswer feature.  If used without\n"
591                         "       argument, displays the current on/off status of autoanswer.\n"
592                         "       The default value of autoanswer is in 'oss.conf'.\n";
593                 return NULL;
594
595         case CLI_GENERATE:
596                 return NULL;
597         }
598
599         if (a->argc == e->args - 1) {
600                 ast_cli(a->fd, "Auto answer is %s.\n", pvt->autoanswer ? "on" : "off");
601                 return CLI_SUCCESS;
602         }
603
604         if (a->argc != e->args)
605                 return CLI_SHOWUSAGE;
606
607         if (!pvt) {
608                 ast_log(LOG_WARNING, "Cannot find device %s (should not happen!)\n",
609                         pvt->name);
610                 return CLI_FAILURE;
611         }
612
613         if (!strcasecmp(a->argv[e->args-1], "on"))
614                 pvt->autoanswer = 1;
615         else if (!strcasecmp(a->argv[e->args - 1], "off"))
616                 pvt->autoanswer = 0;
617         else
618                 return CLI_SHOWUSAGE;
619
620         return CLI_SUCCESS;
621 }
622
623 static char *cli_console_flash(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
624 {
625         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH };
626         struct console_pvt *pvt = &console_pvt;
627
628         if (cmd == CLI_INIT) {
629                 e->command = "console flash";
630                 e->usage =
631                         "Usage: console flash\n"
632                         "       Flashes the call currently placed on the console.\n";
633                 return NULL;
634         } else if (cmd == CLI_GENERATE)
635                 return NULL;
636
637         if (a->argc != e->args)
638                 return CLI_SHOWUSAGE;
639
640         if (!pvt->owner) {
641                 ast_cli(a->fd, "No call to flash\n");
642                 return CLI_FAILURE;
643         }
644
645         pvt->hookstate = 0;
646
647         ast_queue_frame(pvt->owner, &f);
648
649         return CLI_SUCCESS;
650 }
651
652 static char *cli_console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
653 {
654         char *s = NULL;
655         const char *mye = NULL, *myc = NULL; 
656         struct console_pvt *pvt = &console_pvt;
657
658         if (cmd == CLI_INIT) {
659                 e->command = "console dial";
660                 e->usage =
661                         "Usage: console dial [extension[@context]]\n"
662                         "       Dials a given extension (and context if specified)\n";
663                 return NULL;
664         } else if (cmd == CLI_GENERATE)
665                 return NULL;
666
667         if (a->argc > e->args + 1)
668                 return CLI_SHOWUSAGE;
669
670         if (pvt->owner) {       /* already in a call */
671                 int i;
672                 struct ast_frame f = { AST_FRAME_DTMF, 0 };
673
674                 if (a->argc == e->args) {       /* argument is mandatory here */
675                         ast_cli(a->fd, "Already in a call. You can only dial digits until you hangup.\n");
676                         return CLI_FAILURE;
677                 }
678                 s = a->argv[e->args];
679                 /* send the string one char at a time */
680                 for (i = 0; i < strlen(s); i++) {
681                         f.subclass = s[i];
682                         ast_queue_frame(pvt->owner, &f);
683                 }
684                 return CLI_SUCCESS;
685         }
686
687         /* if we have an argument split it into extension and context */
688         if (a->argc == e->args + 1) {
689                 char *ext = NULL, *con = NULL;
690                 s = ast_ext_ctx(pvt, a->argv[e->args], &ext, &con);
691                 ast_debug(1, "provided '%s', exten '%s' context '%s'\n", 
692                         a->argv[e->args], mye, myc);
693                 mye = ext;
694                 myc = con;
695         }
696
697         /* supply default values if needed */
698         if (ast_strlen_zero(mye))
699                 mye = pvt->exten;
700         if (ast_strlen_zero(myc))
701                 myc = pvt->context;
702
703         if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
704                 console_pvt_lock(pvt);
705                 pvt->hookstate = 1;
706                 console_new(pvt, mye, myc, AST_STATE_RINGING);
707                 console_pvt_unlock(pvt);
708         } else
709                 ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
710
711         if (s)
712                 free(s);
713
714         return CLI_SUCCESS;
715 }
716
717 static char *cli_console_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
718 {
719         struct console_pvt *pvt = &console_pvt;
720
721         if (cmd == CLI_INIT) {
722                 e->command = "console hangup";
723                 e->usage =
724                         "Usage: console hangup\n"
725                         "       Hangs up any call currently placed on the console.\n";
726                 return NULL;
727         } else if (cmd == CLI_GENERATE)
728                 return NULL;
729
730         if (a->argc != e->args)
731                 return CLI_SHOWUSAGE;
732
733         if (!pvt->owner && !pvt->hookstate) {
734                 ast_cli(a->fd, "No call to hang up\n");
735                 return CLI_FAILURE;
736         }
737
738         pvt->hookstate = 0;
739         if (pvt->owner)
740                 ast_queue_hangup(pvt->owner);
741
742         return CLI_SUCCESS;
743 }
744
745 static char *cli_console_mute(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
746 {
747         char *s;
748         struct console_pvt *pvt = &console_pvt;
749         
750         if (cmd == CLI_INIT) {
751                 e->command = "console {mute|unmute}";
752                 e->usage =
753                         "Usage: console {mute|unmute}\n"
754                         "       Mute/unmute the microphone.\n";
755                 return NULL;
756         } else if (cmd == CLI_GENERATE)
757                 return NULL;
758
759         if (a->argc != e->args)
760                 return CLI_SHOWUSAGE;
761
762         s = a->argv[e->args-1];
763         if (!strcasecmp(s, "mute"))
764                 pvt->muted = 1;
765         else if (!strcasecmp(s, "unmute"))
766                 pvt->muted = 0;
767         else
768                 return CLI_SHOWUSAGE;
769
770         ast_verb(1, V_BEGIN "The Console is now %s" V_END, 
771                 pvt->muted ? "Muted" : "Unmuted");
772
773         return CLI_SUCCESS;
774 }
775
776 static char *cli_list_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
777 {
778         PaDeviceIndex index, num, def_input, def_output;
779
780         if (cmd == CLI_INIT) {
781                 e->command = "console list devices";
782                 e->usage =
783                         "Usage: console list devices\n"
784                         "       List all available devices.\n";
785                 return NULL;
786         } else if (cmd == CLI_GENERATE)
787                 return NULL;
788
789         if (a->argc != e->args)
790                 return CLI_SHOWUSAGE;
791
792         ast_cli(a->fd, "Available Devices:\n---------------------------------\n");
793
794         num = Pa_GetDeviceCount();
795         if (!num) {
796                 ast_cli(a->fd, "(None)\n");
797                 return CLI_SUCCESS;
798         }
799
800         def_input = Pa_GetDefaultInputDevice();
801         def_output = Pa_GetDefaultOutputDevice();
802         for (index = 0; index < num; index++) {
803                 const PaDeviceInfo *dev = Pa_GetDeviceInfo(index);
804                 if (!dev)
805                         continue;
806                 ast_cli(a->fd, "Device Name: %s\n", dev->name);
807                 if (index == def_input)
808                         ast_cli(a->fd, "    ---> Default Input Device\n");
809                 if (index == def_output)
810                         ast_cli(a->fd, "    ---> Default Output Device\n");
811         }
812
813         return CLI_SUCCESS;
814 }
815
816 /*!
817  * \brief answer command from the console
818  */
819 static char *cli_console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
820 {
821         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
822         struct console_pvt *pvt = &console_pvt;
823
824         switch (cmd) {
825         case CLI_INIT:
826                 e->command = "console answer";
827                 e->usage =
828                         "Usage: console answer\n"
829                         "       Answers an incoming call on the console channel.\n";
830                 return NULL;
831
832         case CLI_GENERATE:
833                 return NULL;    /* no completion */
834         }
835
836         if (a->argc != e->args)
837                 return CLI_SHOWUSAGE;
838
839         if (!pvt->owner) {
840                 ast_cli(a->fd, "No one is calling us\n");
841                 return CLI_FAILURE;
842         }
843
844         pvt->hookstate = 1;
845         ast_queue_frame(pvt->owner, &f);
846
847         return CLI_SUCCESS;
848 }
849
850 /*!
851  * \brief Console send text CLI command
852  *
853  * \note concatenate all arguments into a single string. argv is NULL-terminated
854  * so we can use it right away
855  */
856 static char *cli_console_sendtext(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
857 {
858         char buf[TEXT_SIZE];
859         struct console_pvt *pvt = &console_pvt;
860         struct ast_frame f = {
861                 .frametype = AST_FRAME_TEXT,
862                 .data = buf,
863                 .src = "console_send_text",
864         };
865         int len;
866
867         if (cmd == CLI_INIT) {
868                 e->command = "console send text";
869                 e->usage =
870                         "Usage: console send text <message>\n"
871                         "       Sends a text message for display on the remote terminal.\n";
872                 return NULL;
873         } else if (cmd == CLI_GENERATE)
874                 return NULL;
875
876         if (a->argc < e->args + 1)
877                 return CLI_SHOWUSAGE;
878
879         if (!pvt->owner) {
880                 ast_cli(a->fd, "Not in a call\n");
881                 return CLI_FAILURE;
882         }
883
884         ast_join(buf, sizeof(buf) - 1, a->argv + e->args);
885         if (ast_strlen_zero(buf))
886                 return CLI_SHOWUSAGE;
887
888         len = strlen(buf);
889         buf[len] = '\n';
890         f.datalen = len + 1;
891
892         ast_queue_frame(pvt->owner, &f);
893
894         return CLI_SUCCESS;
895 }
896
897 static struct ast_cli_entry cli_console[] = {
898         AST_CLI_DEFINE(cli_console_dial,       "Dial an extension from the console"),
899         AST_CLI_DEFINE(cli_console_hangup,     "Hangup a call on the console"),
900         AST_CLI_DEFINE(cli_console_mute,       "Disable/Enable mic input"),
901         AST_CLI_DEFINE(cli_console_answer,     "Answer an incoming console call"),
902         AST_CLI_DEFINE(cli_console_sendtext,   "Send text to a connected party"),
903         AST_CLI_DEFINE(cli_console_flash,      "Send a flash to the connected party"),
904         AST_CLI_DEFINE(cli_console_autoanswer, "Turn autoanswer on or off"),
905         AST_CLI_DEFINE(cli_list_devices,       "List available devices"),
906 };
907
908 /*!
909  * \brief Set default values for a pvt struct
910  *
911  * \note This function expects the pvt lock to be held.
912  */
913 static void set_pvt_defaults(struct console_pvt *pvt, int reload)
914 {
915         if (!reload) {
916                 /* This should be changed for multiple device support.  Right now,
917                  * there is no way to change the name of a device.  The default
918                  * input and output sound devices are the only ones supported. */
919                 ast_string_field_set(pvt, name, "default");
920         }
921
922         ast_string_field_set(pvt, mohinterpret, "default");
923         ast_string_field_set(pvt, context, "default");
924         ast_string_field_set(pvt, exten, "s");
925         ast_string_field_set(pvt, language, "");
926         ast_string_field_set(pvt, cid_num, "");
927         ast_string_field_set(pvt, cid_name, "");
928
929         pvt->overridecontext = 0;
930         pvt->autoanswer = 0;
931 }
932
933 static void store_callerid(struct console_pvt *pvt, const char *value)
934 {
935         char cid_name[256];
936         char cid_num[256];
937
938         ast_callerid_split(value, cid_name, sizeof(cid_name), 
939                 cid_num, sizeof(cid_num));
940
941         ast_string_field_set(pvt, cid_name, cid_name);
942         ast_string_field_set(pvt, cid_num, cid_num);
943 }
944
945 /*!
946  * \brief Store a configuration parameter in a pvt struct
947  *
948  * \note This function expects the pvt lock to be held.
949  */
950 static void store_config_core(struct console_pvt *pvt, const char *var, const char *value)
951 {
952         if (!ast_jb_read_conf(&global_jbconf, var, value))
953                 return;
954
955         CV_START(var, value);
956
957         CV_STRFIELD("context", pvt, context);
958         CV_STRFIELD("extension", pvt, exten);
959         CV_STRFIELD("mohinterpret", pvt, mohinterpret);
960         CV_STRFIELD("language", pvt, language);
961         CV_F("callerid", store_callerid(pvt, value));
962         CV_BOOL("overridecontext", pvt->overridecontext);
963         CV_BOOL("autoanswer", pvt->autoanswer);
964         
965         ast_log(LOG_WARNING, "Unknown option '%s'\n", var);
966
967         CV_END;
968 }
969
970 /*!
971  * \brief Load the configuration
972  * \param reload if this was called due to a reload
973  * \retval 0 succcess
974  * \retval -1 failure
975  */
976 static int load_config(int reload)
977 {
978         struct ast_config *cfg;
979         struct ast_variable *v;
980         struct console_pvt *pvt = &console_pvt;
981         struct ast_flags config_flags = { 0 };
982         int res = -1;
983
984         /* default values */
985         memcpy(&global_jbconf, &default_jbconf, sizeof(global_jbconf));
986
987         console_pvt_lock(pvt);
988
989         set_pvt_defaults(pvt, reload);
990
991         if (!(cfg = ast_config_load(config_file, config_flags))) {
992                 ast_log(LOG_NOTICE, "Unable to open configuration file %s!\n", config_file);
993                 goto return_unlock;
994         }
995
996         for (v = ast_variable_browse(cfg, "general"); v; v = v->next)
997                 store_config_core(pvt, v->name, v->value);
998
999         ast_config_destroy(cfg);
1000
1001         res = 0;
1002
1003 return_unlock:
1004         console_pvt_unlock(pvt);
1005         return res;
1006 }
1007
1008 static int init_pvt(struct console_pvt *pvt)
1009 {
1010         if (ast_string_field_init(pvt, 32))
1011                 return -1;
1012         
1013         if (ast_mutex_init(&pvt->__lock)) {
1014                 ast_log(LOG_ERROR, "Failed to initialize mutex\n");
1015                 return -1;
1016         }
1017
1018         return 0;
1019 }
1020
1021 static void destroy_pvt(struct console_pvt *pvt)
1022 {
1023         ast_string_field_free_memory(pvt);
1024         
1025         ast_mutex_destroy(&pvt->__lock);
1026 }
1027
1028 static int unload_module(void)
1029 {
1030         struct console_pvt *pvt = &console_pvt;
1031
1032         if (pvt->hookstate)
1033                 stop_stream(pvt);
1034
1035         Pa_Terminate();
1036
1037         ast_channel_unregister(&console_tech);
1038         ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console));
1039
1040         destroy_pvt(pvt);
1041
1042         return 0;
1043 }
1044
1045 static int load_module(void)
1046 {
1047         PaError res;
1048         struct console_pvt *pvt = &console_pvt;
1049
1050         if (init_pvt(pvt))
1051                 goto return_error;
1052
1053         if (load_config(0))
1054                 goto return_error;
1055
1056         res = Pa_Initialize();
1057         if (res != paNoError) {
1058                 ast_log(LOG_WARNING, "Failed to initialize audio system - (%d) %s\n",
1059                         res, Pa_GetErrorText(res));
1060                 goto return_error_pa_init;
1061         }
1062
1063         if (ast_channel_register(&console_tech)) {
1064                 ast_log(LOG_ERROR, "Unable to register channel type 'Console'\n");
1065                 goto return_error_chan_reg;
1066         }
1067
1068         if (ast_cli_register_multiple(cli_console, ARRAY_LEN(cli_console)))
1069                 goto return_error_cli_reg;
1070
1071         return AST_MODULE_LOAD_SUCCESS;
1072
1073 return_error_cli_reg:
1074         ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console));
1075 return_error_chan_reg:
1076         ast_channel_unregister(&console_tech);
1077 return_error_pa_init:
1078         Pa_Terminate();
1079 return_error:
1080         destroy_pvt(pvt);
1081
1082         return AST_MODULE_LOAD_DECLINE;
1083 }
1084
1085 static int reload(void)
1086 {
1087         return load_config(1);
1088 }
1089
1090 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Console Channel Driver",
1091                 .load = load_module,
1092                 .unload = unload_module,
1093                 .reload = reload,
1094 );