Don't do reinvite if both parties talk diffrent codecs
[asterisk/asterisk.git] / channels / chan_oss.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Use /dev/dsp as a channel, and the console to command it :).
5  *
6  * The full-duplex "simulation" is pretty weak.  This is generally a 
7  * VERY BADLY WRITTEN DRIVER so please don't use it as a model for
8  * writing a driver.
9  * 
10  * Copyright (C) 1999, Mark Spencer
11  *
12  * Mark Spencer <markster@linux-support.net>
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License
16  */
17
18 #include <asterisk/lock.h>
19 #include <asterisk/frame.h>
20 #include <asterisk/logger.h>
21 #include <asterisk/channel.h>
22 #include <asterisk/module.h>
23 #include <asterisk/channel_pvt.h>
24 #include <asterisk/options.h>
25 #include <asterisk/pbx.h>
26 #include <asterisk/config.h>
27 #include <asterisk/cli.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <sys/ioctl.h>
32 #include <sys/time.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #ifdef __linux
37 #include <linux/soundcard.h>
38 #elif defined(__FreeBSD__)
39 #include <machine/soundcard.h>
40 #else
41 #include <soundcard.h>
42 #endif
43 #include "busy.h"
44 #include "ringtone.h"
45 #include "ring10.h"
46 #include "answer.h"
47
48 /* Which device to use */
49 #ifdef __OpenBSD__
50 #define DEV_DSP "/dev/audio"
51 #else
52 #define DEV_DSP "/dev/dsp"
53 #endif
54
55 /* Lets use 160 sample frames, just like GSM.  */
56 #define FRAME_SIZE 160
57
58 /* When you set the frame size, you have to come up with
59    the right buffer format as well. */
60 /* 5 64-byte frames = one frame */
61 #define BUFFER_FMT ((buffersize * 10) << 16) | (0x0006);
62
63 /* Don't switch between read/write modes faster than every 300 ms */
64 #define MIN_SWITCH_TIME 600
65
66 static struct timeval lasttime;
67
68 static int usecnt;
69 static int silencesuppression = 0;
70 static int silencethreshold = 1000;
71
72
73 static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
74
75 static char *type = "Console";
76 static char *desc = "OSS Console Channel Driver";
77 static char *tdesc = "OSS Console Channel Driver";
78 static char *config = "oss.conf";
79
80 static char context[AST_MAX_EXTENSION] = "default";
81 static char language[MAX_LANGUAGE] = "";
82 static char exten[AST_MAX_EXTENSION] = "s";
83
84 static int hookstate=0;
85
86 static short silence[FRAME_SIZE] = {0, };
87
88 struct sound {
89         int ind;
90         short *data;
91         int datalen;
92         int samplen;
93         int silencelen;
94         int repeat;
95 };
96
97 static struct sound sounds[] = {
98         { AST_CONTROL_RINGING, ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
99         { AST_CONTROL_BUSY, busy, sizeof(busy)/2, 4000, 4000, 1 },
100         { AST_CONTROL_CONGESTION, busy, sizeof(busy)/2, 2000, 2000, 1 },
101         { AST_CONTROL_RING, ring10, sizeof(ring10)/2, 16000, 32000, 1 },
102         { AST_CONTROL_ANSWER, answer, sizeof(answer)/2, 2200, 0, 0 },
103 };
104
105 /* Sound command pipe */
106 static int sndcmd[2];
107
108 static struct chan_oss_pvt {
109         /* We only have one OSS structure -- near sighted perhaps, but it
110            keeps this driver as simple as possible -- as it should be. */
111         struct ast_channel *owner;
112         char exten[AST_MAX_EXTENSION];
113         char context[AST_MAX_EXTENSION];
114 } oss;
115
116 static int time_has_passed(void)
117 {
118         struct timeval tv;
119         int ms;
120         gettimeofday(&tv, NULL);
121         ms = (tv.tv_sec - lasttime.tv_sec) * 1000 +
122                         (tv.tv_usec - lasttime.tv_usec) / 1000;
123         if (ms > MIN_SWITCH_TIME)
124                 return -1;
125         return 0;
126 }
127
128 /* Number of buffers...  Each is FRAMESIZE/8 ms long.  For example
129    with 160 sample frames, and a buffer size of 3, we have a 60ms buffer, 
130    usually plenty. */
131
132 static pthread_t sthread;
133
134 #define MAX_BUFFER_SIZE 100
135 static int buffersize = 3;
136
137 static int full_duplex = 0;
138
139 /* Are we reading or writing (simulated full duplex) */
140 static int readmode = 1;
141
142 /* File descriptor for sound device */
143 static int sounddev = -1;
144
145 static int autoanswer = 1;
146  
147 #if 0
148 static int calc_loudness(short *frame)
149 {
150         int sum = 0;
151         int x;
152         for (x=0;x<FRAME_SIZE;x++) {
153                 if (frame[x] < 0)
154                         sum -= frame[x];
155                 else
156                         sum += frame[x];
157         }
158         sum = sum/FRAME_SIZE;
159         return sum;
160 }
161 #endif
162
163 static int cursound = -1;
164 static int sampsent = 0;
165 static int silencelen=0;
166 static int offset=0;
167 static int nosound=0;
168
169 static int send_sound(void)
170 {
171         short myframe[FRAME_SIZE];
172         int total = FRAME_SIZE;
173         short *frame = NULL;
174         int amt=0;
175         int res;
176         int myoff;
177         audio_buf_info abi;
178         if (cursound > -1) {
179                 res = ioctl(sounddev, SNDCTL_DSP_GETOSPACE ,&abi);
180                 if (res) {
181                         ast_log(LOG_WARNING, "Unable to read output space\n");
182                         return -1;
183                 }
184                 /* Calculate how many samples we can send, max */
185                 if (total > (abi.fragments * abi.fragsize / 2)) 
186                         total = abi.fragments * abi.fragsize / 2;
187                 res = total;
188                 if (sampsent < sounds[cursound].samplen) {
189                         myoff=0;
190                         while(total) {
191                                 amt = total;
192                                 if (amt > (sounds[cursound].datalen - offset)) 
193                                         amt = sounds[cursound].datalen - offset;
194                                 memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
195                                 total -= amt;
196                                 offset += amt;
197                                 sampsent += amt;
198                                 myoff += amt;
199                                 if (offset >= sounds[cursound].datalen)
200                                         offset = 0;
201                         }
202                         /* Set it up for silence */
203                         if (sampsent >= sounds[cursound].samplen) 
204                                 silencelen = sounds[cursound].silencelen;
205                         frame = myframe;
206                 } else {
207                         if (silencelen > 0) {
208                                 frame = silence;
209                                 silencelen -= res;
210                         } else {
211                                 if (sounds[cursound].repeat) {
212                                         /* Start over */
213                                         sampsent = 0;
214                                         offset = 0;
215                                 } else {
216                                         cursound = -1;
217                                         nosound = 0;
218                                 }
219                         }
220                 }
221                 if (frame)
222                         res = write(sounddev, frame, res * 2);
223                 if (res > 0)
224                         return 0;
225                 return res;
226         }
227         return 0;
228 }
229
230 static void *sound_thread(void *unused)
231 {
232         fd_set rfds;
233         fd_set wfds;
234         int max;
235         int res;
236         char ign[4096];
237         if (read(sounddev, ign, sizeof(sounddev)) < 0)
238                 ast_log(LOG_WARNING, "Read error on sound device: %s\n", strerror(errno));
239         for(;;) {
240                 FD_ZERO(&rfds);
241                 FD_ZERO(&wfds);
242                 max = sndcmd[0];
243                 FD_SET(sndcmd[0], &rfds);
244                 if (!oss.owner) {
245                         FD_SET(sounddev, &rfds);
246                         if (sounddev > max)
247                                 max = sounddev;
248                 }
249                 if (cursound > -1) {
250                         FD_SET(sounddev, &wfds);
251                         if (sounddev > max)
252                                 max = sounddev;
253                 }
254                 res = ast_select(max + 1, &rfds, &wfds, NULL, NULL);
255                 if (res < 1) {
256                         ast_log(LOG_WARNING, "select failed: %s\n", strerror(errno));
257                         continue;
258                 }
259                 if (FD_ISSET(sndcmd[0], &rfds)) {
260                         read(sndcmd[0], &cursound, sizeof(cursound));
261                         silencelen = 0;
262                         offset = 0;
263                         sampsent = 0;
264                 }
265                 if (FD_ISSET(sounddev, &rfds)) {
266                         /* Ignore read */
267                         if (read(sounddev, ign, sizeof(ign)) < 0)
268                                 ast_log(LOG_WARNING, "Read error on sound device: %s\n", strerror(errno));
269                 }
270                 if (FD_ISSET(sounddev, &wfds))
271                         if (send_sound())
272                                 ast_log(LOG_WARNING, "Failed to write sound\n");
273         }
274         /* Never reached */
275         return NULL;
276 }
277
278 #if 0
279 static int silence_suppress(short *buf)
280 {
281 #define SILBUF 3
282         int loudness;
283         static int silentframes = 0;
284         static char silbuf[FRAME_SIZE * 2 * SILBUF];
285         static int silbufcnt=0;
286         if (!silencesuppression)
287                 return 0;
288         loudness = calc_loudness((short *)(buf));
289         if (option_debug)
290                 ast_log(LOG_DEBUG, "loudness is %d\n", loudness);
291         if (loudness < silencethreshold) {
292                 silentframes++;
293                 silbufcnt++;
294                 /* Keep track of the last few bits of silence so we can play
295                    them as lead-in when the time is right */
296                 if (silbufcnt >= SILBUF) {
297                         /* Make way for more buffer */
298                         memmove(silbuf, silbuf + FRAME_SIZE * 2, FRAME_SIZE * 2 * (SILBUF - 1));
299                         silbufcnt--;
300                 }
301                 memcpy(silbuf + FRAME_SIZE * 2 * silbufcnt, buf, FRAME_SIZE * 2);
302                 if (silentframes > 10) {
303                         /* We've had plenty of silence, so compress it now */
304                         return 1;
305                 }
306         } else {
307                 silentframes=0;
308                 /* Write any buffered silence we have, it may have something
309                    important */
310                 if (silbufcnt) {
311                         write(sounddev, silbuf, silbufcnt * FRAME_SIZE);
312                         silbufcnt = 0;
313                 }
314         }
315         return 0;
316 }
317 #endif
318
319 static int setformat(void)
320 {
321         int fmt, desired, res, fd = sounddev;
322         static int warnedalready = 0;
323         static int warnedalready2 = 0;
324         fmt = AFMT_S16_LE;
325         res = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt);
326         if (res < 0) {
327                 ast_log(LOG_WARNING, "Unable to set format to 16-bit signed\n");
328                 return -1;
329         }
330         res = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
331         if (res >= 0) {
332                 if (option_verbose > 1) 
333                         ast_verbose(VERBOSE_PREFIX_2 "Console is full duplex\n");
334                 full_duplex = -1;
335         }
336         fmt = 0;
337         res = ioctl(fd, SNDCTL_DSP_STEREO, &fmt);
338         if (res < 0) {
339                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
340                 return -1;
341         }
342         /* 8000 Hz desired */
343         desired = 8000;
344         fmt = desired;
345         res = ioctl(fd, SNDCTL_DSP_SPEED, &fmt);
346         if (res < 0) {
347                 ast_log(LOG_WARNING, "Failed to set audio device to mono\n");
348                 return -1;
349         }
350         if (fmt != desired) {
351                 if (!warnedalready++)
352                         ast_log(LOG_WARNING, "Requested %d Hz, got %d Hz -- sound may be choppy\n", desired, fmt);
353         }
354 #if 1
355         fmt = BUFFER_FMT;
356         res = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fmt);
357         if (res < 0) {
358                 if (!warnedalready2++)
359                         ast_log(LOG_WARNING, "Unable to set fragment size -- sound may be choppy\n");
360         }
361 #endif
362         return 0;
363 }
364
365 static int soundcard_setoutput(int force)
366 {
367         /* Make sure the soundcard is in output mode.  */
368         int fd = sounddev;
369         if (full_duplex || (!readmode && !force))
370                 return 0;
371         readmode = 0;
372         if (force || time_has_passed()) {
373                 ioctl(sounddev, SNDCTL_DSP_RESET);
374                 /* Keep the same fd reserved by closing the sound device and copying stdin at the same
375                    time. */
376                 /* dup2(0, sound); */ 
377                 close(sounddev);
378                 fd = open(DEV_DSP, O_WRONLY |O_NONBLOCK);
379                 if (fd < 0) {
380                         ast_log(LOG_WARNING, "Unable to re-open DSP device: %s\n", strerror(errno));
381                         return -1;
382                 }
383                 /* dup2 will close the original and make fd be sound */
384                 if (dup2(fd, sounddev) < 0) {
385                         ast_log(LOG_WARNING, "dup2() failed: %s\n", strerror(errno));
386                         return -1;
387                 }
388                 if (setformat()) {
389                         return -1;
390                 }
391                 return 0;
392         }
393         return 1;
394 }
395
396 static int soundcard_setinput(int force)
397 {
398         int fd = sounddev;
399         if (full_duplex || (readmode && !force))
400                 return 0;
401         readmode = -1;
402         if (force || time_has_passed()) {
403                 ioctl(sounddev, SNDCTL_DSP_RESET);
404                 close(sounddev);
405                 /* dup2(0, sound); */
406                 fd = open(DEV_DSP, O_RDONLY | O_NONBLOCK);
407                 if (fd < 0) {
408                         ast_log(LOG_WARNING, "Unable to re-open DSP device: %s\n", strerror(errno));
409                         return -1;
410                 }
411                 /* dup2 will close the original and make fd be sound */
412                 if (dup2(fd, sounddev) < 0) {
413                         ast_log(LOG_WARNING, "dup2() failed: %s\n", strerror(errno));
414                         return -1;
415                 }
416                 if (setformat()) {
417                         return -1;
418                 }
419                 return 0;
420         }
421         return 1;
422 }
423
424 static int soundcard_init(void)
425 {
426         /* Assume it's full duplex for starters */
427         int fd = open(DEV_DSP,  O_RDWR | O_NONBLOCK);
428         if (fd < 0) {
429                 ast_log(LOG_WARNING, "Unable to open %s: %s\n", DEV_DSP, strerror(errno));
430                 return fd;
431         }
432         gettimeofday(&lasttime, NULL);
433         sounddev = fd;
434         setformat();
435         if (!full_duplex) 
436                 soundcard_setinput(1);
437         return sounddev;
438 }
439
440 static int oss_digit(struct ast_channel *c, char digit)
441 {
442         ast_verbose( " << Console Received digit %c >> \n", digit);
443         return 0;
444 }
445
446 static int oss_text(struct ast_channel *c, char *text)
447 {
448         ast_verbose( " << Console Received text %s >> \n", text);
449         return 0;
450 }
451
452 static int oss_call(struct ast_channel *c, char *dest, int timeout)
453 {
454         int res = 3;
455         struct ast_frame f = { 0, };
456         ast_verbose( " << Call placed to '%s' on console >> \n", dest);
457         if (autoanswer) {
458                 ast_verbose( " << Auto-answered >> \n" );
459                 f.frametype = AST_FRAME_CONTROL;
460                 f.subclass = AST_CONTROL_ANSWER;
461                 ast_queue_frame(c, &f, 0);
462         } else {
463                 nosound = 1;
464                 ast_verbose( " << Type 'answer' to answer, or use 'autoanswer' for future calls >> \n");
465                 f.frametype = AST_FRAME_CONTROL;
466                 f.subclass = AST_CONTROL_RINGING;
467                 ast_queue_frame(c, &f, 0);
468                 write(sndcmd[1], &res, sizeof(res));
469         }
470         return 0;
471 }
472
473 static void answer_sound(void)
474 {
475         int res;
476         nosound = 1;
477         res = 4;
478         write(sndcmd[1], &res, sizeof(res));
479         
480 }
481
482 static int oss_answer(struct ast_channel *c)
483 {
484         ast_verbose( " << Console call has been answered >> \n");
485         answer_sound();
486         ast_setstate(c, AST_STATE_UP);
487         cursound = -1;
488         nosound=0;
489         return 0;
490 }
491
492 static int oss_hangup(struct ast_channel *c)
493 {
494         int res = 0;
495         cursound = -1;
496         c->pvt->pvt = NULL;
497         oss.owner = NULL;
498         ast_verbose( " << Hangup on console >> \n");
499         ast_mutex_lock(&usecnt_lock);
500         usecnt--;
501         ast_mutex_unlock(&usecnt_lock);
502         if (hookstate) {
503                 if (autoanswer) {
504                         /* Assume auto-hangup too */
505                         hookstate = 0;
506                 } else {
507                         /* Make congestion noise */
508                         res = 2;
509                         write(sndcmd[1], &res, sizeof(res));
510                 }
511         }
512         return 0;
513 }
514
515 static int soundcard_writeframe(short *data)
516 {       
517         /* Write an exactly FRAME_SIZE sized of frame */
518         static int bufcnt = 0;
519         static short buffer[FRAME_SIZE * MAX_BUFFER_SIZE * 5];
520         struct audio_buf_info info;
521         int res;
522         int fd = sounddev;
523         static int warned=0;
524         if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info)) {
525                 if (!warned)
526                         ast_log(LOG_WARNING, "Error reading output space\n");
527                 bufcnt = buffersize;
528                 warned++;
529         }
530         if ((info.fragments >= buffersize * 5) && (bufcnt == buffersize)) {
531                 /* We've run out of stuff, buffer again */
532                 bufcnt = 0;
533         }
534         if (bufcnt == buffersize) {
535                 /* Write sample immediately */
536                 res = write(fd, ((void *)data), FRAME_SIZE * 2);
537         } else {
538                 /* Copy the data into our buffer */
539                 res = FRAME_SIZE * 2;
540                 memcpy(buffer + (bufcnt * FRAME_SIZE), data, FRAME_SIZE * 2);
541                 bufcnt++;
542                 if (bufcnt == buffersize) {
543                         res = write(fd, ((void *)buffer), FRAME_SIZE * 2 * buffersize);
544                 }
545         }
546         return res;
547 }
548
549
550 static int oss_write(struct ast_channel *chan, struct ast_frame *f)
551 {
552         int res;
553         static char sizbuf[8000];
554         static int sizpos = 0;
555         int len = sizpos;
556         int pos;
557         /* Immediately return if no sound is enabled */
558         if (nosound)
559                 return 0;
560         /* Stop any currently playing sound */
561         cursound = -1;
562         if (!full_duplex) {
563                 /* If we're half duplex, we have to switch to read mode
564                    to honor immediate needs if necessary */
565                 res = soundcard_setinput(1);
566                 if (res < 0) {
567                         ast_log(LOG_WARNING, "Unable to set device to input mode\n");
568                         return -1;
569                 }
570                 return 0;
571         }
572         res = soundcard_setoutput(0);
573         if (res < 0) {
574                 ast_log(LOG_WARNING, "Unable to set output device\n");
575                 return -1;
576         } else if (res > 0) {
577                 /* The device is still in read mode, and it's too soon to change it,
578                    so just pretend we wrote it */
579                 return 0;
580         }
581         /* We have to digest the frame in 160-byte portions */
582         if (f->datalen > sizeof(sizbuf) - sizpos) {
583                 ast_log(LOG_WARNING, "Frame too large\n");
584                 return -1;
585         }
586         memcpy(sizbuf + sizpos, f->data, f->datalen);
587         len += f->datalen;
588         pos = 0;
589         while(len - pos > FRAME_SIZE * 2) {
590                 soundcard_writeframe((short *)(sizbuf + pos));
591                 pos += FRAME_SIZE * 2;
592         }
593         if (len - pos) 
594                 memmove(sizbuf, sizbuf + pos, len - pos);
595         sizpos = len - pos;
596         return 0;
597 }
598
599 static struct ast_frame *oss_read(struct ast_channel *chan)
600 {
601         static struct ast_frame f;
602         static char buf[FRAME_SIZE * 2 + AST_FRIENDLY_OFFSET];
603         static int readpos = 0;
604         int res;
605         
606 #if 0
607         ast_log(LOG_DEBUG, "oss_read()\n");
608 #endif
609                 
610         f.frametype = AST_FRAME_NULL;
611         f.subclass = 0;
612         f.samples = 0;
613         f.datalen = 0;
614         f.data = NULL;
615         f.offset = 0;
616         f.src = type;
617         f.mallocd = 0;
618         
619         res = soundcard_setinput(0);
620         if (res < 0) {
621                 ast_log(LOG_WARNING, "Unable to set input mode\n");
622                 return NULL;
623         }
624         if (res > 0) {
625                 /* Theoretically shouldn't happen, but anyway, return a NULL frame */
626                 return &f;
627         }
628         res = read(sounddev, buf + AST_FRIENDLY_OFFSET + readpos, FRAME_SIZE * 2 - readpos);
629         if (res < 0) {
630                 ast_log(LOG_WARNING, "Error reading from sound device (If you're running 'artsd' then kill it): %s\n", strerror(errno));
631 #if 0
632                 CRASH;
633 #endif          
634                 return NULL;
635         }
636         readpos += res;
637         
638         if (readpos >= FRAME_SIZE * 2) {
639                 /* A real frame */
640                 readpos = 0;
641                 if (chan->_state != AST_STATE_UP) {
642                         /* Don't transmit unless it's up */
643                         return &f;
644                 }
645                 f.frametype = AST_FRAME_VOICE;
646                 f.subclass = AST_FORMAT_SLINEAR;
647                 f.samples = FRAME_SIZE;
648                 f.datalen = FRAME_SIZE * 2;
649                 f.data = buf + AST_FRIENDLY_OFFSET;
650                 f.offset = AST_FRIENDLY_OFFSET;
651                 f.src = type;
652                 f.mallocd = 0;
653 #if 0
654                 { static int fd = -1;
655                   if (fd < 0)
656                         fd = open("output.raw", O_RDWR | O_TRUNC | O_CREAT);
657                   write(fd, f.data, f.datalen);
658                 }
659 #endif          
660         }
661         return &f;
662 }
663
664 static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
665 {
666         struct chan_oss_pvt *p = newchan->pvt->pvt;
667         p->owner = newchan;
668         return 0;
669 }
670
671 static int oss_indicate(struct ast_channel *chan, int cond)
672 {
673         int res;
674         switch(cond) {
675         case AST_CONTROL_BUSY:
676                 res = 1;
677                 break;
678         case AST_CONTROL_CONGESTION:
679                 res = 2;
680                 break;
681         case AST_CONTROL_RINGING:
682                 res = 0;
683                 break;
684         default:
685                 ast_log(LOG_WARNING, "Don't know how to display condition %d on %s\n", cond, chan->name);
686                 return -1;
687         }
688         if (res > -1) {
689                 write(sndcmd[1], &res, sizeof(res));
690         }
691         return 0;       
692 }
693
694 static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
695 {
696         struct ast_channel *tmp;
697         tmp = ast_channel_alloc(1);
698         if (tmp) {
699                 snprintf(tmp->name, sizeof(tmp->name), "OSS/%s", DEV_DSP + 5);
700                 tmp->type = type;
701                 tmp->fds[0] = sounddev;
702                 tmp->nativeformats = AST_FORMAT_SLINEAR;
703                 tmp->pvt->pvt = p;
704                 tmp->pvt->send_digit = oss_digit;
705                 tmp->pvt->send_text = oss_text;
706                 tmp->pvt->hangup = oss_hangup;
707                 tmp->pvt->answer = oss_answer;
708                 tmp->pvt->read = oss_read;
709                 tmp->pvt->call = oss_call;
710                 tmp->pvt->write = oss_write;
711                 tmp->pvt->indicate = oss_indicate;
712                 tmp->pvt->fixup = oss_fixup;
713                 if (strlen(p->context))
714                         strncpy(tmp->context, p->context, sizeof(tmp->context)-1);
715                 if (strlen(p->exten))
716                         strncpy(tmp->exten, p->exten, sizeof(tmp->exten)-1);
717                 if (strlen(language))
718                         strncpy(tmp->language, language, sizeof(tmp->language)-1);
719                 p->owner = tmp;
720                 ast_setstate(tmp, state);
721                 ast_mutex_lock(&usecnt_lock);
722                 usecnt++;
723                 ast_mutex_unlock(&usecnt_lock);
724                 ast_update_use_count();
725                 if (state != AST_STATE_DOWN) {
726                         if (ast_pbx_start(tmp)) {
727                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
728                                 ast_hangup(tmp);
729                                 tmp = NULL;
730                         }
731                 }
732         }
733         return tmp;
734 }
735
736 static struct ast_channel *oss_request(char *type, int format, void *data)
737 {
738         int oldformat = format;
739         struct ast_channel *tmp;
740         format &= AST_FORMAT_SLINEAR;
741         if (!format) {
742                 ast_log(LOG_NOTICE, "Asked to get a channel of format '%d'\n", oldformat);
743                 return NULL;
744         }
745         if (oss.owner) {
746                 ast_log(LOG_NOTICE, "Already have a call on the OSS channel\n");
747                 return NULL;
748         }
749         tmp= oss_new(&oss, AST_STATE_DOWN);
750         if (!tmp) {
751                 ast_log(LOG_WARNING, "Unable to create new OSS channel\n");
752         }
753         return tmp;
754 }
755
756 static int console_autoanswer(int fd, int argc, char *argv[])
757 {
758         if ((argc != 1) && (argc != 2))
759                 return RESULT_SHOWUSAGE;
760         if (argc == 1) {
761                 ast_cli(fd, "Auto answer is %s.\n", autoanswer ? "on" : "off");
762                 return RESULT_SUCCESS;
763         } else {
764                 if (!strcasecmp(argv[1], "on"))
765                         autoanswer = -1;
766                 else if (!strcasecmp(argv[1], "off"))
767                         autoanswer = 0;
768                 else
769                         return RESULT_SHOWUSAGE;
770         }
771         return RESULT_SUCCESS;
772 }
773
774 static char *autoanswer_complete(char *line, char *word, int pos, int state)
775 {
776 #ifndef MIN
777 #define MIN(a,b) ((a) < (b) ? (a) : (b))
778 #endif
779         switch(state) {
780         case 0:
781                 if (strlen(word) && !strncasecmp(word, "on", MIN(strlen(word), 2)))
782                         return strdup("on");
783         case 1:
784                 if (strlen(word) && !strncasecmp(word, "off", MIN(strlen(word), 3)))
785                         return strdup("off");
786         default:
787                 return NULL;
788         }
789         return NULL;
790 }
791
792 static char autoanswer_usage[] =
793 "Usage: autoanswer [on|off]\n"
794 "       Enables or disables autoanswer feature.  If used without\n"
795 "       argument, displays the current on/off status of autoanswer.\n"
796 "       The default value of autoanswer is in 'oss.conf'.\n";
797
798 static int console_answer(int fd, int argc, char *argv[])
799 {
800         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
801         if (argc != 1)
802                 return RESULT_SHOWUSAGE;
803         if (!oss.owner) {
804                 ast_cli(fd, "No one is calling us\n");
805                 return RESULT_FAILURE;
806         }
807         hookstate = 1;
808         cursound = -1;
809         ast_queue_frame(oss.owner, &f, 1);
810         answer_sound();
811         return RESULT_SUCCESS;
812 }
813
814 static char sendtext_usage[] =
815 "Usage: send text <message>\n"
816 "       Sends a text message for display on the remote terminal.\n";
817
818 static int console_sendtext(int fd, int argc, char *argv[])
819 {
820         int tmparg = 2;
821         char text2send[256];
822         struct ast_frame f = { 0, };
823         if (argc < 2)
824                 return RESULT_SHOWUSAGE;
825         if (!oss.owner) {
826                 ast_cli(fd, "No one is calling us\n");
827                 return RESULT_FAILURE;
828         }
829         if (strlen(text2send))
830                 ast_cli(fd, "Warning: message already waiting to be sent, overwriting\n");
831         strcpy(text2send, "");
832         while(tmparg < argc) {
833                 strncat(text2send, argv[tmparg++], sizeof(text2send) - strlen(text2send));
834                 strncat(text2send, " ", sizeof(text2send) - strlen(text2send));
835         }
836         if (strlen(text2send)) {
837                 f.frametype = AST_FRAME_TEXT;
838                 f.subclass = 0;
839                 f.data = text2send;
840                 f.datalen = strlen(text2send);
841                 ast_queue_frame(oss.owner, &f, 1);
842         }
843         return RESULT_SUCCESS;
844 }
845
846 static char answer_usage[] =
847 "Usage: answer\n"
848 "       Answers an incoming call on the console (OSS) channel.\n";
849
850 static int console_hangup(int fd, int argc, char *argv[])
851 {
852         if (argc != 1)
853                 return RESULT_SHOWUSAGE;
854         cursound = -1;
855         if (!oss.owner && !hookstate) {
856                 ast_cli(fd, "No call to hangup up\n");
857                 return RESULT_FAILURE;
858         }
859         hookstate = 0;
860         if (oss.owner) {
861                 ast_queue_hangup(oss.owner, 1);
862         }
863         return RESULT_SUCCESS;
864 }
865
866 static char hangup_usage[] =
867 "Usage: hangup\n"
868 "       Hangs up any call currently placed on the console.\n";
869
870
871 static int console_dial(int fd, int argc, char *argv[])
872 {
873         char tmp[256], *tmp2;
874         char *mye, *myc;
875         int x;
876         struct ast_frame f = { AST_FRAME_DTMF, 0 };
877         if ((argc != 1) && (argc != 2))
878                 return RESULT_SHOWUSAGE;
879         if (oss.owner) {
880                 if (argc == 2) {
881                         for (x=0;x<strlen(argv[1]);x++) {
882                                 f.subclass = argv[1][x];
883                                 ast_queue_frame(oss.owner, &f, 1);
884                         }
885                 } else {
886                         ast_cli(fd, "You're already in a call.  You can use this only to dial digits until you hangup\n");
887                         return RESULT_FAILURE;
888                 }
889                 return RESULT_SUCCESS;
890         }
891         mye = exten;
892         myc = context;
893         if (argc == 2) {
894                 char *stringp=NULL;
895                 strncpy(tmp, argv[1], sizeof(tmp)-1);
896                 stringp=tmp;
897                 strsep(&stringp, "@");
898                 tmp2 = strsep(&stringp, "@");
899                 if (strlen(tmp))
900                         mye = tmp;
901                 if (tmp2 && strlen(tmp2))
902                         myc = tmp2;
903         }
904         if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
905                 strncpy(oss.exten, mye, sizeof(oss.exten)-1);
906                 strncpy(oss.context, myc, sizeof(oss.context)-1);
907                 hookstate = 1;
908                 oss_new(&oss, AST_STATE_RINGING);
909         } else
910                 ast_cli(fd, "No such extension '%s' in context '%s'\n", mye, myc);
911         return RESULT_SUCCESS;
912 }
913
914 static char dial_usage[] =
915 "Usage: dial [extension[@context]]\n"
916 "       Dials a given extensison (";
917
918 static int console_transfer(int fd, int argc, char *argv[])
919 {
920         char tmp[256];
921         char *context;
922         if (argc != 2)
923                 return RESULT_SHOWUSAGE;
924         if (oss.owner && oss.owner->bridge) {
925                 strncpy(tmp, argv[1], sizeof(tmp) - 1);
926                 context = strchr(tmp, '@');
927                 if (context) {
928                         *context = '\0';
929                         context++;
930                 } else
931                         context = oss.owner->context;
932                 if (ast_exists_extension(oss.owner->bridge, context, tmp, 1, oss.owner->bridge->callerid)) {
933                         ast_cli(fd, "Whee, transferring %s to %s@%s.\n", 
934                                         oss.owner->bridge->name, tmp, context);
935                         if (ast_async_goto(oss.owner->bridge, context, tmp, 1, 1))
936                                 ast_cli(fd, "Failed to transfer :(\n");
937                 } else {
938                         ast_cli(fd, "No such extension exists\n");
939                 }
940         } else {
941                 ast_cli(fd, "There is no call to transfer\n");
942         }
943         return RESULT_SUCCESS;
944 }
945
946 static char transfer_usage[] =
947 "Usage: transfer <extension>[@context]\n"
948 "       Transfers the currently connected call to the given extension (and\n"
949 "context if specified)\n";
950
951 static struct ast_cli_entry myclis[] = {
952         { { "answer", NULL }, console_answer, "Answer an incoming console call", answer_usage },
953         { { "hangup", NULL }, console_hangup, "Hangup a call on the console", hangup_usage },
954         { { "dial", NULL }, console_dial, "Dial an extension on the console", dial_usage },
955         { { "transfer", NULL }, console_transfer, "Transfer a call to a different extension", transfer_usage },
956         { { "send", "text", NULL }, console_sendtext, "Send text to the remote device", sendtext_usage },
957         { { "autoanswer", NULL }, console_autoanswer, "Sets/displays autoanswer", autoanswer_usage, autoanswer_complete }
958 };
959
960 int load_module()
961 {
962         int res;
963         int x;
964         struct ast_config *cfg;
965         struct ast_variable *v;
966         res = pipe(sndcmd);
967         if (res) {
968                 ast_log(LOG_ERROR, "Unable to create pipe\n");
969                 return -1;
970         }
971         res = soundcard_init();
972         if (res < 0) {
973                 if (option_verbose > 1) {
974                         ast_verbose(VERBOSE_PREFIX_2 "No sound card detected -- console channel will be unavailable\n");
975                         ast_verbose(VERBOSE_PREFIX_2 "Turn off OSS support by adding 'noload=chan_oss.so' in /etc/asterisk/modules.conf\n");
976                 }
977                 return 0;
978         }
979         if (!full_duplex)
980                 ast_log(LOG_WARNING, "XXX I don't work right with non-full duplex sound cards XXX\n");
981         res = ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR, oss_request);
982         if (res < 0) {
983                 ast_log(LOG_ERROR, "Unable to register channel class '%s'\n", type);
984                 return -1;
985         }
986         for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
987                 ast_cli_register(myclis + x);
988         if ((cfg = ast_load(config))) {
989                 v = ast_variable_browse(cfg, "general");
990                 while(v) {
991                         if (!strcasecmp(v->name, "autoanswer"))
992                                 autoanswer = ast_true(v->value);
993                         else if (!strcasecmp(v->name, "silencesuppression"))
994                                 silencesuppression = ast_true(v->value);
995                         else if (!strcasecmp(v->name, "silencethreshold"))
996                                 silencethreshold = atoi(v->value);
997                         else if (!strcasecmp(v->name, "context"))
998                                 strncpy(context, v->value, sizeof(context)-1);
999                         else if (!strcasecmp(v->name, "language"))
1000                                 strncpy(language, v->value, sizeof(language)-1);
1001                         else if (!strcasecmp(v->name, "extension"))
1002                                 strncpy(exten, v->value, sizeof(exten)-1);
1003                         v=v->next;
1004                 }
1005                 ast_destroy(cfg);
1006         }
1007         pthread_create(&sthread, NULL, sound_thread, NULL);
1008         return 0;
1009 }
1010
1011
1012
1013 int unload_module()
1014 {
1015         int x;
1016         for (x=0;x<sizeof(myclis)/sizeof(struct ast_cli_entry); x++)
1017                 ast_cli_unregister(myclis + x);
1018         close(sounddev);
1019         if (sndcmd[0] > 0) {
1020                 close(sndcmd[0]);
1021                 close(sndcmd[1]);
1022         }
1023         if (oss.owner)
1024                 ast_softhangup(oss.owner, AST_SOFTHANGUP_APPUNLOAD);
1025         if (oss.owner)
1026                 return -1;
1027         return 0;
1028 }
1029
1030 char *description()
1031 {
1032         return desc;
1033 }
1034
1035 int usecount()
1036 {
1037         int res;
1038         ast_mutex_lock(&usecnt_lock);
1039         res = usecnt;
1040         ast_mutex_unlock(&usecnt_lock);
1041         return res;
1042 }
1043
1044 char *key()
1045 {
1046         return ASTERISK_GPL_KEY;
1047 }