5f476cdf64fa5822ccb9b7de56d7f4f99e80ddb8
[asterisk/asterisk.git] / channels / chan_ixj.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * QuickNet Internet Phone Jack Channel
5  * 
6  * Copyright (C) 1999, Adtran Inc. and Linux Support Services, LLC
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <stdio.h>
15 #include <pthread.h>
16 #include <string.h>
17 #include <asterisk/channel.h>
18 #include <asterisk/channel_pvt.h>
19 #include <asterisk/config.h>
20 #include <asterisk/logger.h>
21 #include <asterisk/module.h>
22 #include <asterisk/pbx.h>
23 #include <asterisk/options.h>
24 #include <sys/socket.h>
25 #include <sys/time.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <arpa/inet.h>
30 #include <fcntl.h>
31 #include <sys/ioctl.h>
32 #include <linux/if_packet.h>
33 #include <linux/if_ether.h>
34 #include "ixjuser.h"
35 #include "DialTone.h"
36
37 #define IXJ_MAX_BUF 480
38
39 static char *desc = "QuickNet Internet Phone Jack";
40 static char *type = "PhoneJack";
41 static char *tdesc = "QuickNet Internet Phone Jack";
42 static char *config = "ixj.conf";
43
44 /* Default context for dialtone mode */
45 static char context[AST_MAX_EXTENSION] = "default";
46
47 char *ignore_rcs_id_for_chan_ixj = ixjuser_h_rcsid;
48
49 static int usecnt =0;
50 static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
51
52 /* Protect the interface list (of ixj_pvt's) */
53 static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
54
55 /* Protect the monitoring thread, so only one process can kill or start it, and not
56    when it's doing something critical. */
57 static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
58
59 /* This is the thread for the monitor which checks for input on the channels
60    which are not currently in use.  */
61 static pthread_t monitor_thread = -1;
62
63 static int restart_monitor();
64
65 /* The private structures of the Phone Jack channels are linked for
66    selecting outgoing channels */
67    
68 #define MODE_DIALTONE   1
69 #define MODE_IMMEDIATE  2
70    
71 static struct ixj_pvt {
72         int fd;                                                 /* Raw file descriptor for this device */
73         struct ast_channel *owner;              /* Channel we belong to, possibly NULL */
74         int mode;                                               /* Is this in the  */
75         int lastformat;                                 /* Last output format */
76         int lastinput;                                  /* Last input format */
77         int ministate;                                  /* Miniature state, for dialtone mode */
78         char dev[256];                                  /* Device name */
79         struct ixj_pvt *next;                   /* Next channel in list */
80         struct ast_frame fr;                    /* Frame */
81         char offset[AST_FRIENDLY_OFFSET];
82         char buf[IXJ_MAX_BUF];                                  /* Static buffer for reading frames */
83         int obuflen;
84         int dialtone;
85         char context[AST_MAX_EXTENSION];
86         char obuf[IXJ_MAX_BUF * 2];
87         char ext[AST_MAX_EXTENSION];
88 } *iflist = NULL;
89
90 static int ixj_digit(struct ast_channel *ast, char digit)
91 {
92         struct ixj_pvt *p;
93         int outdigit;
94         p = ast->pvt->pvt;
95         switch(digit) {
96         case '0':
97         case '1':
98         case '2':
99         case '3':
100         case '4':
101         case '5':
102         case '6':
103         case '7':
104         case '8':
105         case '9':
106                 outdigit = digit - '0' + 1;
107                 break;
108         case '*':
109                 outdigit = 11;
110                 break;
111         case '#':
112                 outdigit = 12;
113                 break;
114         default:
115                 ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
116                 return -1;
117         }
118         ioctl(p->fd, IXJCTL_PLAY_TONE, digit);
119         return 0;
120 }
121
122 static int ixj_call(struct ast_channel *ast, char *dest, int timeout)
123 {
124         struct ixj_pvt *p;
125         p = ast->pvt->pvt;
126         if ((ast->state != AST_STATE_DOWN) && (ast->state != AST_STATE_RESERVED)) {
127                 ast_log(LOG_WARNING, "ixj_call called on %s, neither down nor reserved\n", ast->name);
128                 return -1;
129         }
130         /* When we call, it just works, really, there's no destination...  Just
131            ring the phone and wait for someone to answer */
132         ast_log(LOG_DEBUG, "Ringing %s on %s (%d)\n", dest, ast->name, ast->fd);
133         ioctl(p->fd, IXJCTL_RING_START);
134         ast->state = AST_STATE_RINGING;
135         return 0;
136 }
137
138 static int ixj_hangup(struct ast_channel *ast)
139 {
140         struct ixj_pvt *p;
141         p = ast->pvt->pvt;
142         ast_log(LOG_DEBUG, "ixj_hangup(%s)\n", ast->name);
143         if (!ast->pvt->pvt) {
144                 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
145                 return 0;
146         }
147         /* XXX Is there anything we can do to really hang up except stop recording? */
148         ast->state = AST_STATE_DOWN;
149         if (ioctl(p->fd, IXJCTL_REC_STOP))
150                 ast_log(LOG_WARNING, "Failed to stop recording\n");
151         if (ioctl(p->fd, IXJCTL_PLAY_STOP))
152                 ast_log(LOG_WARNING, "Failed to stop playing\n");
153         if (ioctl(p->fd, IXJCTL_RING_STOP))
154                 ast_log(LOG_WARNING, "Failed to stop ringing\n");
155         if (ioctl(p->fd, IXJCTL_CPT_STOP))
156                 ast_log(LOG_WARNING, "Failed to stop sounds\n");
157         /* If they're off hook, give a busy signal */
158         if (ioctl(p->fd, IXJCTL_HOOKSTATE))
159                 ioctl(p->fd, IXJCTL_BUSY);
160         p->lastformat = -1;
161         p->lastinput = -1;
162         p->ministate = 0;
163         p->obuflen = 0;
164         p->dialtone = 0;
165         memset(p->ext, 0, sizeof(p->ext));
166         ((struct ixj_pvt *)(ast->pvt->pvt))->owner = NULL;
167         pthread_mutex_lock(&usecnt_lock);
168         usecnt--;
169         if (usecnt < 0) 
170                 ast_log(LOG_WARNING, "Usecnt < 0???\n");
171         pthread_mutex_unlock(&usecnt_lock);
172         ast_update_use_count();
173         if (option_verbose > 2) 
174                 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
175         ast->pvt->pvt = NULL;
176         ast->state = AST_STATE_DOWN;
177         restart_monitor();
178         return 0;
179 }
180
181 static int ixj_setup(struct ast_channel *ast)
182 {
183         struct ixj_pvt *p;
184         p = ast->pvt->pvt;
185         ioctl(p->fd, IXJCTL_CPT_STOP);
186         /* Nothing to answering really, just start recording */
187         if (ast->format & AST_FORMAT_G723_1) {
188                 /* Prefer g723 */
189                 ioctl(p->fd, IXJCTL_REC_STOP);
190                 if (p->lastinput != AST_FORMAT_G723_1) {
191                         p->lastinput = AST_FORMAT_G723_1;
192                         if (ioctl(p->fd, IXJCTL_REC_CODEC, G723_63)) {
193                                 ast_log(LOG_WARNING, "Failed to set codec to g723.1\n");
194                                 return -1;
195                         }
196                 }
197         } else if (ast->format & AST_FORMAT_SLINEAR) {
198                 ioctl(p->fd, IXJCTL_REC_STOP);
199                 if (p->lastinput != AST_FORMAT_SLINEAR) {
200                         p->lastinput = AST_FORMAT_SLINEAR;
201                         if (ioctl(p->fd, IXJCTL_REC_CODEC, LINEAR16)) {
202                                 ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");
203                                 return -1;
204                         }
205                 }
206         } else {
207                 ast_log(LOG_WARNING, "Can't do format %d\n", ast->format);
208                 return -1;
209         }
210         if (ioctl(p->fd, IXJCTL_REC_START)) {
211                 ast_log(LOG_WARNING, "Failed to start recording\n");
212                 return -1;
213         }
214         return 0;
215 }
216
217 static int ixj_answer(struct ast_channel *ast)
218 {
219         ixj_setup(ast);
220         ast_log(LOG_DEBUG, "ixj_answer(%s)\n", ast->name);
221         ast->rings = 0;
222         ast->state = AST_STATE_UP;
223         return 0;
224 }
225
226 static char ixj_2digit(char c)
227 {
228         if (c == 12)
229                 return '#';
230         else if (c == 11)
231                 return '*';
232         else if ((c < 10) && (c >= 0))
233                 return '0' + c - 1;
234         else
235                 return '?';
236 }
237
238 static struct ast_frame  *ixj_read(struct ast_channel *ast)
239 {
240         int res;
241         IXJ_EXCEPTION ixje;
242         struct ixj_pvt *p = ast->pvt->pvt;
243         char digit;
244
245         /* Some nice norms */
246         p->fr.datalen = 0;
247         p->fr.timelen = 0;
248         p->fr.data =  NULL;
249         p->fr.src = type;
250         p->fr.offset = 0;
251         p->fr.mallocd=0;
252
253         ixje.bytes = ioctl(p->fd, IXJCTL_EXCEPTION);
254         if (ixje.bits.dtmf_ready)  {
255                 /* We've got a digit -- Just handle this nicely and easily */
256                 digit =  ioctl(p->fd, IXJCTL_GET_DTMF_ASCII);
257                 p->fr.subclass = digit;
258                 p->fr.frametype = AST_FRAME_DTMF;
259                 return &p->fr;
260         }
261         if (ixje.bits.hookstate) {
262                 res = ioctl(p->fd, IXJCTL_HOOKSTATE);
263                 /* See if we've gone on hook, if so, notify by returning NULL */
264                 if (!res)
265                         return NULL;
266                 else {
267                         if (ast->state == AST_STATE_RINGING) {
268                                 /* They've picked up the phone */
269                                 p->fr.frametype = AST_FRAME_CONTROL;
270                                 p->fr.subclass = AST_CONTROL_ANSWER;
271                                 ixj_setup(ast);
272                                 ast->state = AST_STATE_UP;
273                                 return &p->fr;
274                         }  else 
275                                 ast_log(LOG_WARNING, "Got off hook in weird state\n");
276                 }
277         }
278 #if 0
279         if (ixje.bits.pstn_ring)
280                 ast_verbose("Unit is ringing\n");
281         if (ixje.bits.caller_id) {
282                 ast_verbose("We have caller ID: %s\n");
283         }
284 #endif
285         /* Try to read some data... */
286         CHECK_BLOCKING(ast);
287         res = read(p->fd, p->buf, IXJ_MAX_BUF);
288         ast->blocking = 0;
289         if (res < 0) {
290                 ast_log(LOG_WARNING, "Error reading: %s\n", strerror(errno));
291                 return NULL;
292         }
293         p->fr.data = p->buf;
294         p->fr.datalen = res;
295         p->fr.frametype = AST_FRAME_VOICE;
296         p->fr.subclass = p->lastinput;
297         p->fr.offset = AST_FRIENDLY_OFFSET;
298         return &p->fr;
299 }
300
301 static int ixj_write_buf(struct ixj_pvt *p, char *buf, int len, int frlen)
302 {
303         int res;
304         /* Store as much of the buffer as we can, then write fixed frames */
305         int space = sizeof(p->obuf) - p->obuflen;
306         /* Make sure we have enough buffer space to store the frame */
307         if (space < len)
308                 len = space;
309         memcpy(p->obuf + p->obuflen, buf, len);
310         p->obuflen += len;
311         while(p->obuflen > frlen) {
312 #if 0
313                 res = frlen;
314                 ast_log(LOG_DEBUG, "Wrote %d bytes\n", res);
315 #else
316                 res = write(p->fd, p->obuf, frlen);
317 #endif
318                 if (res != frlen) {
319                         if (res < 1) {
320                                 ast_log(LOG_WARNING, "Write failed: %s\n", strerror(errno));
321                                 return -1;
322                         } else {
323                                 ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frlen);
324                         }
325                 }
326                 p->obuflen -= frlen;
327                 /* Move memory if necessary */
328                 if (p->obuflen) 
329                         memmove(p->obuf, p->obuf + frlen, p->obuflen);
330         }
331         return len;
332 }
333
334 static int ixj_write(struct ast_channel *ast, struct ast_frame *frame)
335 {
336         struct ixj_pvt *p = ast->pvt->pvt;
337         int res;
338         int maxfr=0;
339         char *pos;
340         int sofar;
341         int expected;
342         /* Write a frame of (presumably voice) data */
343         if (frame->frametype != AST_FRAME_VOICE) {
344                 ast_log(LOG_WARNING, "Don't know what to do with  frame type '%d'\n", frame->frametype);
345                 ast_frfree(frame);
346                 return -1;
347         }
348         if (!(frame->subclass & (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR))) {
349                 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
350                 ast_frfree(frame);
351                 return -1;
352         }
353         if (frame->subclass == AST_FORMAT_G723_1) {
354                 if (p->lastformat != AST_FORMAT_G723_1) {
355                         ioctl(p->fd, IXJCTL_PLAY_STOP);
356                         if (ioctl(p->fd, IXJCTL_PLAY_CODEC, G723_63)) {
357                                 ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
358                                 return -1;
359                         }
360                         p->lastformat = AST_FORMAT_G723_1;
361                         /* Reset output buffer */
362                         p->obuflen = 0;
363                 }
364                 if (frame->datalen > 24) {
365                         ast_log(LOG_WARNING, "Frame size too large for G.723.1 (%d bytes)\n", frame->datalen);
366                         return -1;
367                 }
368                 maxfr = 24;
369         } else if (frame->subclass == AST_FORMAT_SLINEAR) {
370                 if (p->lastformat != AST_FORMAT_SLINEAR) {
371                         ioctl(p->fd, IXJCTL_PLAY_STOP);
372                         if (ioctl(p->fd, IXJCTL_PLAY_CODEC, LINEAR16)) {
373                                 ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
374                                 return -1;
375                         }
376                         p->lastformat = AST_FORMAT_SLINEAR;
377                         /* Reset output buffer */
378                         p->obuflen = 0;
379                 }
380                 maxfr = 480;
381         }
382         if (ioctl(p->fd, IXJCTL_PLAY_START)) {
383                 ast_log(LOG_WARNING, "Failed to start recording\n");
384                 return -1;
385         }
386         /* If we get here, we have a voice frame of Appropriate data */
387         sofar = 0;
388         pos = frame->data;
389         while(sofar < frame->datalen) {
390                 /* Write in no more than maxfr sized frames */
391                 expected = frame->datalen - sofar;
392                 if (maxfr < expected)
393                         expected = maxfr;
394                 /* XXX Internet Phone Jack does not handle the 4-byte VAD frame properly! XXX */
395                 if (frame->datalen != 4) {
396                         res = ixj_write_buf(p, pos, expected, maxfr);
397                         if (res != expected) {
398                                 if (res < 0) 
399                                         ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));
400                                 else
401                                         ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);
402                                 return -1;
403                         }
404                         sofar += res;
405                         pos += res;
406                 } else
407                         sofar += 4;
408         }
409         return 0;
410 }
411
412 static struct ast_channel *ixj_new(struct ixj_pvt *i, int state)
413 {
414         struct ast_channel *tmp;
415         tmp = ast_channel_alloc();
416         if (tmp) {
417                 snprintf(tmp->name, sizeof(tmp->name), "PhoneJack/%s", i->dev + 5);
418                 tmp->type = type;
419                 tmp->fd = i->fd;
420                 /* XXX Switching formats silently causes kernel panics XXX */
421                 tmp->format = AST_FORMAT_G723_1 /* | AST_FORMAT_SLINEAR */;
422                 tmp->state = state;
423                 if (state == AST_STATE_RING)
424                         tmp->rings = 1;
425                 tmp->pvt->pvt = i;
426                 tmp->pvt->send_digit = ixj_digit;
427                 tmp->pvt->call = ixj_call;
428                 tmp->pvt->hangup = ixj_hangup;
429                 tmp->pvt->answer = ixj_answer;
430                 tmp->pvt->read = ixj_read;
431                 tmp->pvt->write = ixj_write;
432                 strncpy(tmp->context, i->context, sizeof(tmp->context));
433                 if (strlen(i->ext))
434                         strncpy(tmp->exten, i->ext, sizeof(tmp->exten));
435                 i->owner = tmp;
436                 pthread_mutex_lock(&usecnt_lock);
437                 usecnt++;
438                 pthread_mutex_unlock(&usecnt_lock);
439                 ast_update_use_count();
440                 if (state != AST_STATE_DOWN) {
441                         if (state == AST_STATE_RING)
442                                 ioctl(tmp->fd, IXJCTL_RINGBACK);
443                         if (ast_pbx_start(tmp)) {
444                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
445                                 ast_hangup(tmp);
446                         }
447                 }
448         } else
449                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
450         return tmp;
451 }
452
453 static void ixj_mini_packet(struct ixj_pvt *i)
454 {
455         int res;
456         char buf[1024];
457         /* Ignore stuff we read... */
458         res = read(i->fd, buf, sizeof(buf));
459         if (res < 1) {
460                 ast_log(LOG_WARNING, "Read returned %d\n", res);
461                 return;
462         }
463 }
464
465 static void ixj_check_exception(struct ixj_pvt *i)
466 {
467         int offhook=0;
468         char digit[2] = {0 , 0};
469         IXJ_EXCEPTION ixje;
470         /* XXX Do something XXX */
471 #if 0
472         ast_log(LOG_DEBUG, "Exception!\n");
473 #endif
474         ixje.bytes = ioctl(i->fd, IXJCTL_EXCEPTION);
475         if (ixje.bits.dtmf_ready)  {
476                 digit[0] = ioctl(i->fd, IXJCTL_GET_DTMF_ASCII);
477                 if (i->mode == MODE_DIALTONE) {
478                         ioctl(i->fd, IXJCTL_PLAY_STOP);
479                         ioctl(i->fd, IXJCTL_REC_STOP);
480                         ioctl(i->fd, IXJCTL_CPT_STOP);
481                         i->dialtone = 0;
482                         if (strlen(i->ext) < AST_MAX_EXTENSION - 1)
483                                 strcat(i->ext, digit);
484                         if (ast_exists_extension(NULL, i->context, i->ext, 1)) {
485                                 /* It's a valid extension in its context, get moving! */
486                                 ixj_new(i, AST_STATE_UP);
487                                 /* No need to restart monitor, we are the monitor */
488                                 if (i->owner) {
489                                         ixj_setup(i->owner);
490                                 }
491                         } else if (ast_exists_extension(NULL, "default", i->ext, 1)) {
492                                 /* Check the default, too... */
493                                 /* XXX This should probably be justified better XXX */
494                                 strncpy(i->context, "default", sizeof(i->context));
495                                 ixj_new(i, AST_STATE_UP);
496                                 if (i->owner) {
497                                         ixj_setup(i->owner);
498                                 }
499                         } else if ((strlen(i->ext) >= ast_pbx_longest_extension(i->context)) &&
500                                            (strlen(i->ext) >= ast_pbx_longest_extension("default"))) {
501                                 /* It's not a valid extension, give a busy signal */
502                                 ioctl(i->fd, IXJCTL_BUSY);
503                         }
504 #if 0
505                         ast_verbose("Extension is %s\n", i->ext);
506 #endif
507                 }
508         }
509         if (ixje.bits.hookstate) {
510                 offhook = ioctl(i->fd, IXJCTL_HOOKSTATE);
511                 if (offhook) {
512                         if (i->mode == MODE_IMMEDIATE) {
513                                 ixj_new(i, AST_STATE_RING);
514                         } else if (i->mode == MODE_DIALTONE) {
515 #if 0
516                                 /* XXX Bug in the Phone jack, you can't detect DTMF when playing a tone XXX */
517                                 ioctl(i->fd, IXJCTL_DIALTONE);
518 #else
519                                 /* Play the dialtone */
520                                 i->dialtone++;
521                                 ioctl(i->fd, IXJCTL_PLAY_STOP);
522                                 ioctl(i->fd, IXJCTL_PLAY_CODEC, ULAW);
523                                 ioctl(i->fd, IXJCTL_PLAY_START);
524 #endif
525                         }
526                 } else {
527                         memset(i->ext, 0, sizeof(i->ext));
528                         ioctl(i->fd, IXJCTL_CPT_STOP);
529                         ioctl(i->fd, IXJCTL_PLAY_STOP);
530                         ioctl(i->fd, IXJCTL_REC_STOP);
531                         i->dialtone = 0;
532                 }
533         }
534         if (ixje.bits.pstn_ring)
535                 ast_verbose("Unit is ringing\n");
536         if (ixje.bits.caller_id)
537                 ast_verbose("We have caller ID\n");
538         
539         
540 }
541
542 static void *do_monitor(void *data)
543 {
544         fd_set rfds, efds;
545         int n, res;
546         struct ixj_pvt *i;
547         int tonepos = 0;
548         /* The tone we're playing this round */
549         struct timeval tv = {0,0};
550         int dotone;
551         /* This thread monitors all the frame relay interfaces which are not yet in use
552            (and thus do not have a separate thread) indefinitely */
553         /* From here on out, we die whenever asked */
554         if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
555                 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
556                 return NULL;
557         }
558         for(;;) {
559                 /* Don't let anybody kill us right away.  Nobody should lock the interface list
560                    and wait for the monitor list, but the other way around is okay. */
561                 if (pthread_mutex_lock(&monlock)) {
562                         ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
563                         return NULL;
564                 }
565                 /* Lock the interface list */
566                 if (pthread_mutex_lock(&iflock)) {
567                         ast_log(LOG_ERROR, "Unable to grab interface lock\n");
568                         pthread_mutex_unlock(&monlock);
569                         return NULL;
570                 }
571                 /* Build the stuff we're going to select on, that is the socket of every
572                    ixj_pvt that does not have an associated owner channel */
573                 n = -1;
574                 FD_ZERO(&rfds);
575                 FD_ZERO(&efds);
576                 i = iflist;
577                 dotone = 0;
578                 while(i) {
579                         if (FD_ISSET(i->fd, &rfds)) 
580                                 ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
581                         if (!i->owner) {
582                                 /* This needs to be watched, as it lacks an owner */
583                                 FD_SET(i->fd, &rfds);
584                                 FD_SET(i->fd, &efds);
585                                 if (i->fd > n)
586                                         n = i->fd;
587                                 if (i->dialtone) {
588                                         /* Remember we're going to have to come back and play
589                                            more dialtones */
590                                         if (!tv.tv_usec && !tv.tv_sec) {
591                                                 /* If we're due for a dialtone, play one */
592                                                 if (write(i->fd, DialTone + tonepos, 240) != 240)
593                                                         ast_log(LOG_WARNING, "Dial tone write error\n");
594                                         }
595                                         dotone++;
596                                 }
597                         }
598                         
599                         i = i->next;
600                 }
601                 /* Okay, now that we know what to do, release the interface lock */
602                 pthread_mutex_unlock(&iflock);
603                 
604                 /* And from now on, we're okay to be killed, so release the monitor lock as well */
605                 pthread_mutex_unlock(&monlock);
606                 /* Wait indefinitely for something to happen */
607                 if (dotone) {
608                         /* If we're ready to recycle the time, set it to 30 ms */
609                         tonepos += 240;
610                         if (tonepos >= sizeof(DialTone))
611                                         tonepos = 0;
612                         if (!tv.tv_usec && !tv.tv_sec) {
613                                 tv.tv_usec = 30000;
614                                 tv.tv_sec = 0;
615                         }
616                         res = select(n + 1, &rfds, NULL, &efds, &tv);
617                 } else {
618                         res = select(n + 1, &rfds, NULL, &efds, NULL);
619                         tv.tv_usec = 0;
620                         tv.tv_sec = 0;
621                         tonepos = 0;
622                 }
623                 /* Okay, select has finished.  Let's see what happened.  */
624                 if (res < 0) {
625                         ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
626                         continue;
627                 }
628                 /* If there are no fd's changed, just continue, it's probably time
629                    to play some more dialtones */
630                 if (!res)
631                         continue;
632                 /* Alright, lock the interface list again, and let's look and see what has
633                    happened */
634                 if (pthread_mutex_lock(&iflock)) {
635                         ast_log(LOG_WARNING, "Unable to lock the interface list\n");
636                         continue;
637                 }
638                 i = iflist;
639                 while(i) {
640                         if (FD_ISSET(i->fd, &rfds)) {
641                                 if (i->owner) {
642                                         ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d, %s)...\n", i->fd, i->dev);
643                                         continue;
644                                 }
645                                 ixj_mini_packet(i);
646                         }
647                         if (FD_ISSET(i->fd, &efds)) {
648                                 if (i->owner) {
649                                         ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d, %s)...\n", i->fd, i->dev);
650                                         continue;
651                                 }
652                                 ixj_check_exception(i);
653                         }
654                         i=i->next;
655                 }
656                 pthread_mutex_unlock(&iflock);
657         }
658         /* Never reached */
659         return NULL;
660         
661 }
662
663 static int restart_monitor()
664 {
665         /* If we're supposed to be stopped -- stay stopped */
666         if (monitor_thread == -2)
667                 return 0;
668         if (pthread_mutex_lock(&monlock)) {
669                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
670                 return -1;
671         }
672         if (monitor_thread == pthread_self()) {
673                 pthread_mutex_unlock(&monlock);
674                 ast_log(LOG_WARNING, "Cannot kill myself\n");
675                 return -1;
676         }
677         if (monitor_thread != -1) {
678                 pthread_cancel(monitor_thread);
679 #if 0
680                 pthread_join(monitor_thread, NULL);
681 #endif
682         }
683         /* Start a new monitor */
684         if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
685                 pthread_mutex_unlock(&monlock);
686                 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
687                 return -1;
688         }
689         pthread_mutex_unlock(&monlock);
690         return 0;
691 }
692
693 struct ixj_pvt *mkif(char *iface, int mode)
694 {
695         /* Make a ixj_pvt structure for this interface */
696         struct ixj_pvt *tmp;
697         int flags;      
698         
699         tmp = malloc(sizeof(struct ixj_pvt));
700         if (tmp) {
701                 tmp->fd = open(iface, O_RDWR);
702                 if (tmp->fd < 0) {
703                         ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
704                         free(tmp);
705                         return NULL;
706                 }
707                 ioctl(tmp->fd, IXJCTL_PLAY_STOP);
708                 ioctl(tmp->fd, IXJCTL_REC_STOP);
709                 ioctl(tmp->fd, IXJCTL_RING_STOP);
710                 ioctl(tmp->fd, IXJCTL_CPT_STOP);
711                 tmp->mode = mode;
712                 flags = fcntl(tmp->fd, F_GETFL);
713                 fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
714                 tmp->owner = NULL;
715                 tmp->lastformat = -1;
716                 tmp->lastinput = -1;
717                 tmp->ministate = 0;
718                 memset(tmp->ext, 0, sizeof(tmp->ext));
719                 strncpy(tmp->dev, iface, sizeof(tmp->dev));
720                 strncpy(tmp->context, context, sizeof(tmp->context));
721                 tmp->next = NULL;
722                 tmp->obuflen = 0;
723                 tmp->dialtone = 0;
724         }
725         return tmp;
726 }
727
728 static struct ast_channel *ixj_request(char *type, int format, void *data)
729 {
730         int oldformat;
731         struct ixj_pvt *p;
732         struct ast_channel *tmp = NULL;
733         char *name = data;
734         
735         oldformat = format;
736         format &= (AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR);
737         if (!format) {
738                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
739                 return NULL;
740         }
741         /* Search for an unowned channel */
742         if (pthread_mutex_lock(&iflock)) {
743                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
744                 return NULL;
745         }
746         p = iflist;
747         while(p) {
748                 if (!strcmp(name, p->dev + 5)) {
749                         if (!p->owner) {
750                                 tmp = ixj_new(p, AST_STATE_DOWN);
751                                 break;
752                         }
753                 }
754                 p = p->next;
755         }
756         pthread_mutex_unlock(&iflock);
757         restart_monitor();
758         return tmp;
759 }
760
761 int load_module()
762 {
763         struct ast_config *cfg;
764         struct ast_variable *v;
765         struct ixj_pvt *tmp;
766         int mode = MODE_IMMEDIATE;
767         cfg = ast_load(config);
768
769         /* We *must* have a config file otherwise stop immediately */
770         if (!cfg) {
771                 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
772                 return -1;
773         }
774         if (pthread_mutex_lock(&iflock)) {
775                 /* It's a little silly to lock it, but we mind as well just to be sure */
776                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
777                 return -1;
778         }
779         v = ast_variable_browse(cfg, "interfaces");
780         while(v) {
781                 /* Create the interface list */
782                 if (!strcasecmp(v->name, "device")) {
783                                 tmp = mkif(v->value, mode);
784                                 if (tmp) {
785                                         tmp->next = iflist;
786                                         iflist = tmp;
787                                         
788                                 } else {
789                                         ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
790                                         ast_destroy(cfg);
791                                         pthread_mutex_unlock(&iflock);
792                                         unload_module();
793                                         return -1;
794                                 }
795                 } else if (!strcasecmp(v->name, "mode")) {
796                         if (!strncasecmp(v->value, "di", 2)) 
797                                 mode = MODE_DIALTONE;
798                         else if (!strncasecmp(v->value, "im", 2))
799                                 mode = MODE_IMMEDIATE;
800                         else
801                                 ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
802                 } else if (!strcasecmp(v->name, "context")) {
803                         strncpy(context, v->value, sizeof(context));
804                 }
805                 v = v->next;
806         }
807         pthread_mutex_unlock(&iflock);
808         /* Make sure we can register our Adtranixj channel type */
809         if (ast_channel_register(type, tdesc, AST_FORMAT_G723_1, ixj_request)) {
810                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
811                 ast_destroy(cfg);
812                 unload_module();
813                 return -1;
814         }
815         ast_destroy(cfg);
816         /* And start the monitor for the first time */
817         restart_monitor();
818         return 0;
819 }
820
821
822
823 int unload_module()
824 {
825         struct ixj_pvt *p, *pl;
826         /* First, take us out of the channel loop */
827         ast_channel_unregister(type);
828         if (!pthread_mutex_lock(&iflock)) {
829                 /* Hangup all interfaces if they have an owner */
830                 p = iflist;
831                 while(p) {
832                         if (p->owner)
833                                 ast_softhangup(p->owner);
834                         p = p->next;
835                 }
836                 iflist = NULL;
837                 pthread_mutex_unlock(&iflock);
838         } else {
839                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
840                 return -1;
841         }
842         if (!pthread_mutex_lock(&monlock)) {
843                 if (monitor_thread > -1) {
844                         pthread_cancel(monitor_thread);
845                         pthread_join(monitor_thread, NULL);
846                 }
847                 monitor_thread = -2;
848                 pthread_mutex_unlock(&monlock);
849         } else {
850                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
851                 return -1;
852         }
853
854         if (!pthread_mutex_lock(&iflock)) {
855                 /* Destroy all the interfaces and free their memory */
856                 p = iflist;
857                 while(p) {
858                         /* Close the socket, assuming it's real */
859                         if (p->fd > -1)
860                                 close(p->fd);
861                         pl = p;
862                         p = p->next;
863                         /* Free associated memory */
864                         free(pl);
865                 }
866                 iflist = NULL;
867                 pthread_mutex_unlock(&iflock);
868         } else {
869                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
870                 return -1;
871         }
872                 
873         return 0;
874 }
875
876 int usecount()
877 {
878         int res;
879         pthread_mutex_lock(&usecnt_lock);
880         res = usecnt;
881         pthread_mutex_unlock(&usecnt_lock);
882         return res;
883 }
884
885 char *description()
886 {
887         return desc;
888 }
889