Version 0.1.8 from FTP
[asterisk/asterisk.git] / channels / chan_vofr.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Implementation of Voice over Frame Relay, Adtran Style
5  * 
6  * Copyright (C) 1999, Mark Spencer
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 <errno.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <fcntl.h>
29 #include <arpa/inet.h>
30 #include <linux/if_packet.h>
31 #include <linux/if_ether.h>
32 #ifndef OLD_SANGOMA_API
33 #include <linux/if_wanpipe.h>
34 #include <linux/wanpipe.h>
35 #endif
36 #include <sys/signal.h>
37 #include "adtranvofr.h"
38
39 /* #define VOFRDUMPER */
40
41 #define G723_MAX_BUF 2048
42
43 #define FR_API_MESS 16
44
45 static char *desc = "Adtran Voice over Frame Relay";
46 static char *type = "AdtranVoFR";
47 static char *tdesc = "Voice over Frame Relay/Adtran style";
48 static char *config = "adtranvofr.conf";
49
50 static char context[AST_MAX_EXTENSION] = "default";
51
52 static char language[MAX_LANGUAGE] = "";
53
54 static int usecnt =0;
55 static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
56
57 /* Protect the interface list (of vofr_pvt's) */
58 static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
59
60 /* Protect the monitoring thread, so only one process can kill or start it, and not
61    when it's doing something critical. */
62 static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
63
64 /* This is the thread for the monitor which checks for input on the channels
65    which are not currently in use.  */
66 static pthread_t monitor_thread = 0;
67
68 static int restart_monitor(void);
69
70 /* The private structures of the Adtran VoFR channels are linked for
71    selecting outgoing channels */
72    
73 static struct vofr_pvt {
74         int s;                                                  /* Raw socket for this DLCI */
75 #ifdef OLD_SANGOMA_API
76         struct sockaddr_pkt sa;                 /* Sockaddr needed for sending, also has iface name */
77 #else
78         struct wan_sockaddr_ll sa;              /* Wanpipe sockaddr */
79 #endif
80         struct ast_channel *owner;              /* Channel we belong to, possibly NULL */
81         int outgoing;                                   /* Does this channel support outgoing calls? */
82         struct vofr_pvt *next;                  /* Next channel in list */
83         struct vofr_hdr *hdr;                           /* VOFR header version of buf */
84         struct vofr_hdr *ohdr;
85         u_int8_t dlcih;                                 /* High two bits of DLCI */
86         u_int8_t dlcil;                                 /* Bottom two bits of DLCI */
87         u_int8_t cid;                                   /* Call ID */
88         char buf[G723_MAX_BUF];                                 /* Static buffer for reading frames */
89         char obuf[G723_MAX_BUF];                                /* Output buffer */
90         char context[AST_MAX_EXTENSION];
91         char language[MAX_LANGUAGE];
92         int ringgothangup;                              /* Have we received exactly one hangup after a ring */
93 } *iflist = NULL;
94
95 #ifdef VOFRDUMPER
96
97 /* Some useful debugging routines */
98
99 static char *set(int val)
100 {
101         return (val ? "Set  " : "Unset");
102 }
103
104 static char *controlstr(int control)
105 {
106         switch(control) {
107         case VOFR_CONTROL_ADTRAN:
108                 return "Adtran Proprietary";
109         case VOFR_CONTROL_VOICE:
110                 return "Voice";
111         case VOFR_CONTROL_RFC1490:
112                 return "RFC 1490";
113         }
114         return "Unknown";
115 }
116
117 static char *dtypestr(int control)
118 {
119         switch(control) {
120         case VOFR_TYPE_SIGNAL:
121                 return "Signal Frame";
122         case VOFR_TYPE_VOICE:
123                 return "Voice Frame";
124         case VOFR_TYPE_ANSWER:
125                 return "Answer Tone";
126         case VOFR_TYPE_FAX:     
127                 return "FAX";
128         case VOFR_TYPE_DTMF:
129                 return "DTMF Digit";
130         }
131         return "Unknown";
132 }
133
134 static char *vflagsstr(int flags)
135 {
136         static char buf[80];
137         buf[0] = '\0';
138         if (!flags)
139                 return "(None)";
140         if (flags & VOFR_ROUTE_LOCAL)
141                 strcat(buf, "Local ");
142         if (flags & VOFR_ROUTE_VOICE)
143                 strcat(buf, "Voice ");
144         if (flags & VOFR_ROUTE_DTE)
145                 strcat(buf, "DTE ");
146         else if (flags & VOFR_ROUTE_DTE1)
147                 strcat(buf, "DTE1 ");
148         else if (flags & VOFR_ROUTE_DTE2)       
149                 strcat(buf, "DTE2 ");
150         return buf;
151 }
152
153 static char *remidstr(int remid)
154 {
155         switch(remid) {
156         case VOFR_CARD_TYPE_UNSPEC:
157                 return "Unspecified";
158         case VOFR_CARD_TYPE_FXS:
159                 return "FXS";
160         case VOFR_CARD_TYPE_FXO:
161                 return "FXO";
162         case VOFR_CARD_TYPE_ENM:        
163                 return "E&M";
164         case VOFR_CARD_TYPE_VCOM:       
165                 return "Atlas/VCOM";
166         }
167         return "Unknown";
168 }
169
170 static char *modulationstr(int modulation)
171 {
172         switch(modulation) {
173         case VOFR_MODULATION_SINGLE:
174                 return "Single Frequency";
175         case VOFR_MODULATION_V21:
176                 return "V.21";
177         case VOFR_MODULATION_V27ter_2:
178                 return "V.27 (2400bps)";
179         case VOFR_MODULATION_V27ter_4:
180                 return "V.27 (4800bps)";
181         case VOFR_MODULATION_V29_7:
182                 return "V.29 (7200bps)";
183         case VOFR_MODULATION_V29_9:
184                 return "V.29 (9600bps)";
185         case VOFR_MODULATION_V33_12:
186                 return "V.33 (12000bps)";
187         case VOFR_MODULATION_V33_14:
188                 return "V.33 (14400BPS)";
189         }
190         return "Unknown";
191 }
192
193 static char *signalstr(int signal)
194 {
195         switch(signal) {
196         case VOFR_SIGNAL_ON_HOOK:
197                 return "On Hook";
198         case VOFR_SIGNAL_OFF_HOOK:
199                 return "Off Hook";
200         case VOFR_SIGNAL_RING:
201                 return "Ring";
202         case VOFR_SIGNAL_SWITCHED_DIAL:
203                 return "Switched Dial";
204         case VOFR_SIGNAL_BUSY:
205                 return "Busy";
206         case VOFR_SIGNAL_TRUNK_BUSY:
207                 return "Trunk Busy";
208         }
209         return "Unknown";
210 }
211
212 static char *vofr_digitstr(int val)
213 {
214         static char num[5];
215         if (val < 10) {
216                 snprintf(num, sizeof(num), "%d", val);
217                 return num;
218         }
219         switch(val) {
220         case 10:
221                 return "*";
222         case 11:
223                 return "#";
224         }
225         return "Unknown";
226 }
227
228
229 static void vofr_dump_packet(struct vofr_hdr *vh, int len)
230 {
231         printf("VoFR Packet Dump\n");
232         printf("================\n");
233         printf("EI: %s ", set(vh->control & VOFR_MASK_EI));
234         printf("LI: %s\n", set(vh->control & VOFR_MASK_LI));
235         printf("Control: %s (0x%02x)\n", 
236                 controlstr(vh->control & VOFR_MASK_CONTROL), vh->control & VOFR_MASK_CONTROL);
237         printf("Data Type: %s (0x%02x)\n", dtypestr(vh->dtype), vh->dtype);
238         if (vh->dtype == VOFR_TYPE_SIGNAL) {
239                 printf(" \\--Signal: %s (0x%02x)\n", signalstr(vh->data[0]), vh->data[0]);
240         }
241         if (vh->dtype == VOFR_TYPE_DTMF) {
242                 printf(" \\--Digit: %s (0x%02x)\n", vofr_digitstr(vh->data[0]), vh->data[0]);
243         }
244         printf("Connect Tag: 0x%02x\n", vh->ctag);
245         printf("Voice Rt Flags: %s\n", vflagsstr(vh->vflags));
246         printf("DLCI X-Ref: %d\n", (vh->dlcih << 8) | (vh->dlcil));
247         printf("Channel ID: %d\n", vh->cid);
248         printf("Remote ID: %s (0x%02x)\n", remidstr(vh->remid), vh->remid);
249         printf("Modulation: %s (0x%02x)\n", modulationstr(vh->mod), vh->mod);
250         printf("\n");
251         fflush(stdout);
252 }
253
254 #endif
255
256 static struct ast_frame  *vofr_read(struct ast_channel *ast);
257
258 static int vofr_xmit(struct vofr_pvt *p, char *data, int len)
259 {
260         int res;
261 #ifdef OLD_SANGOMA_API
262     res=sendto(p->s, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_pkt));
263 #else
264     res=sendto(p->s, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct wan_sockaddr_ll));
265 #endif
266         if (res != len) {
267                 ast_log(LOG_WARNING, "vofr_xmit returned %d\n", res);
268         }
269         return res;
270 }
271
272 static int vofr_digit(struct ast_channel *ast, char digit)
273 {
274         /*
275          * T H I S   I S   T O T A L L Y   U N D O C U M E N T E D
276          *     A N D   D O E S   N O T   S O U N D   R I G H T
277          *   XXX Figure out how to really send a decent digit XXX
278          */
279         struct vofr_pvt *p;
280         struct vofr_hdr *vh;
281         p = ast->pvt->pvt;
282         vh = p->ohdr;
283         vh->control = VOFR_CONTROL_VOICE;
284         vh->dtype = VOFR_TYPE_DTMF;
285         vh->vflags = VOFR_ROUTE_NONE;
286         vh->dlcih = p->dlcih;
287         vh->dlcil = p->dlcil;
288         vh->cid = p->cid;
289         vh->remid = VOFR_CARD_TYPE_ASTERISK;
290         vh->mod = VOFR_MODULATION_SINGLE;
291         if ((digit >= '0') && (digit <= '9'))
292                 vh->data[0] = digit - '0';
293         else if (digit == '*')
294                 vh->data[0] = 10;
295         else if (digit == '#')
296                 vh->data[0] = 11;
297         else {
298                 ast_log(LOG_WARNING, "%s: tried to dial a non digit '%c'\n", ast->name, digit);
299                 return -1;
300         }
301         vh->data[1] = 0x14;
302         vh->data[2] = 0x1f;
303         vh->data[3] = 0x70;
304                 /* We sorta start the digit */
305         vofr_xmit(p, p->obuf, VOFR_HDR_SIZE + 4 + FR_API_MESS);
306         usleep(30000);
307                 /* And terminate with an empty voice frame */
308         vh->control = VOFR_CONTROL_VOICE;
309         vh->dtype = VOFR_TYPE_VOICE;
310         vh->vflags = VOFR_ROUTE_NONE;
311         vh->dlcih = p->dlcih;
312         vh->dlcil = p->dlcil;
313         vh->cid = p->cid;
314         vh->remid = VOFR_CARD_TYPE_ASTERISK;
315         vh->mod = VOFR_MODULATION_SINGLE;
316         vofr_xmit(p, p->obuf, VOFR_HDR_SIZE + FR_API_MESS);
317         return 0;
318 }
319
320 static int vofr_xmit_signal(struct vofr_pvt *p, int signal, int pad)
321 {
322         /* Prepare and transmit outgoing buffer with given signal and
323            pad the end with *pad* bytes of data presumed to already
324            be in the buffer (like DTMF tones, etc) */
325         struct vofr_hdr *vh = p->ohdr;
326         int res;
327     vh->control = VOFR_CONTROL_VOICE;
328     vh->dtype = VOFR_TYPE_SIGNAL;
329     vh->vflags = VOFR_ROUTE_NONE;
330     vh->dlcih = p->dlcih;
331     vh->dlcil = p->dlcil;
332     vh->cid = p->cid;
333     vh->remid = VOFR_CARD_TYPE_ASTERISK;
334     vh->mod = VOFR_MODULATION_SINGLE;
335     vh->data[0] = signal;
336         if (FR_API_MESS)
337                 memset(p->obuf, 0, FR_API_MESS);
338         res = vofr_xmit(p, p->obuf,  VOFR_HDR_SIZE + pad + 1 + FR_API_MESS);
339         return res;
340
341 }
342
343 static int vofr_call(struct ast_channel *ast, char *dest, int timeout)
344 {
345         int res;
346         int otimeout;
347         struct ast_frame *f;
348         struct vofr_pvt *p;
349         p = ast->pvt->pvt;
350         if ((ast->state != AST_STATE_DOWN) && (ast->state != AST_STATE_RESERVED)) {
351                 ast_log(LOG_WARNING, "vofr_call called on %s, neither down nor reserved\n", ast->name);
352                 return -1;
353         }
354         /* Take the system off hook */
355         vofr_xmit_signal(p, VOFR_SIGNAL_OFFHOOK, 0);
356         /* Wait for an acknowledgement */
357         otimeout = 1000;
358         while(otimeout) {
359                 otimeout = ast_waitfor(ast, 1000);
360                 if (otimeout < 1) {
361                         ast_log(LOG_WARNING, "Unable to take line '%s' off hook\n", ast->name);
362                         /* Musta gotten hung up, or no ack on off hook */
363                         return -1;      
364                 }
365                 f = vofr_read(ast);
366                 if (!f)
367                         return -1;
368                 if ((f->frametype == AST_FRAME_CONTROL) &&
369                     (f->subclass == AST_CONTROL_OFFHOOK)) 
370                         /* Off hook */
371                                 break;
372         }
373         if (!otimeout) {
374                 ast_log(LOG_WARNING, "Unable to take line off hook\n");
375                 return -1;
376         }
377         /* Send the digits */
378         while(*dest) {
379                 ast->state = AST_STATE_DIALING;
380                 vofr_digit(ast, *dest);
381                 /* Wait .1 seconds before dialing next digit */
382                 usleep(100000);
383                 dest++;
384         }
385         if (timeout) {
386                 /* Wait for the ack that it's ringing */
387                 otimeout = 1000;
388                 while(otimeout) {
389                         otimeout = ast_waitfor(ast, 1000);
390                         if (otimeout < 1) {
391                                 ast_log(LOG_WARNING, "No acknowledgement for ringing\n");
392                                 /* Musta gotten hung up, or no ack on off hook */
393                                 return -1;      
394                         }
395                         f = vofr_read(ast);
396                         if (!f) 
397                                 return -1;
398                         
399                         if (f->frametype == AST_FRAME_CONTROL) {
400                             if (f->subclass == AST_CONTROL_RINGING) {
401                                         ast->state = AST_STATE_RINGING;
402                                         /* We're ringing -- good enough */
403                                         break;
404                                 }
405                                 if (f->subclass == AST_CONTROL_BUSY)
406                                 /* It's busy */
407                                         return -1;
408                         }
409                         ast_frfree(f);
410                 }               
411         }
412         otimeout = timeout;
413         while(timeout) {
414                 /* Wait for an answer, up to timeout... */
415                 res = ast_waitfor(ast, timeout);
416                 if (res < 0)
417                         /* Musta gotten hung up */
418                         return -1;
419                 else
420                         timeout = res;
421                 if (res) {
422                         /* Ooh, read what's there. */
423                         f = vofr_read(ast);
424                         if (!f)
425                                 return -1;
426                         if ((f->frametype == AST_FRAME_CONTROL) && 
427                             (f->subclass == AST_CONTROL_ANSWER)) 
428                                 /* Got an answer -- return the # of ms it took */
429                                 return otimeout - res;
430                                 
431                 }
432         }
433         return 0;
434 }
435
436 static int send_hangup(struct vofr_pvt *p)
437 {
438         /* Just send the hangup sequence */
439         return vofr_xmit_signal(p, 0x80, 0);
440 }
441
442 static int vofr_hangup(struct ast_channel *ast)
443 {
444         int res;
445         if (option_debug)
446                 ast_log(LOG_DEBUG, "vofr_hangup(%s)\n", ast->name);
447         if (!ast->pvt->pvt) {
448                 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
449                 return 0;
450         }
451         res = send_hangup(ast->pvt->pvt);
452         if (res < 0) {
453                 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
454                 return -1;
455         }
456         ast->state = AST_STATE_DOWN;
457         ((struct vofr_pvt *)(ast->pvt->pvt))->owner = NULL;
458         ((struct vofr_pvt *)(ast->pvt->pvt))->ringgothangup = 0;
459         ast_pthread_mutex_lock(&usecnt_lock);
460         usecnt--;
461         if (usecnt < 0) 
462                 ast_log(LOG_WARNING, "Usecnt < 0???\n");
463         ast_pthread_mutex_unlock(&usecnt_lock);
464         ast_update_use_count();
465         if (option_verbose > 2) 
466                 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
467         ast->pvt->pvt = NULL;
468         ast->state = AST_STATE_DOWN;
469         restart_monitor();
470         return 0;
471 }
472
473 static int vofr_answer(struct ast_channel *ast)
474 {
475         int res;
476         int cnt = 1000;
477         char buf[2048];
478         struct vofr_hdr *vh;
479         ast->rings = 0;
480         if (option_debug)
481                 ast_log(LOG_DEBUG, "vofr_answer(%s)\n", ast->name);
482         res = vofr_xmit_signal(ast->pvt->pvt, VOFR_SIGNAL_OFFHOOK, 0);
483         if (res < 0)
484                 ast_log(LOG_WARNING, "Unable to anaswer line %s\n", ast->name);
485         ast->state = AST_STATE_UP;
486         while(cnt > 0) {
487                 cnt = ast_waitfor(ast, cnt);
488                 if (cnt > 0) {
489                         res = read(ast->fds[0], buf, sizeof(buf));
490 #ifdef VOFRDUMPER
491                                 vofr_dump_packet((void *)(buf +FR_API_MESS), res - FR_API_MESS);
492 #endif
493                         res -= FR_API_MESS;
494                         if (res < 0)
495                                 ast_log(LOG_WARNING, "Warning:  read failed (%s) on %s\n", strerror(errno), ast->name);
496                         else {
497                                 /* We're looking for an answer */
498                                 vh = (struct vofr_hdr *)(buf + FR_API_MESS);
499                                 switch(vh->dtype) {
500                                 case VOFR_TYPE_SIGNAL:
501                                         switch(vh->data[0]) {
502                                         case VOFR_SIGNAL_UNKNOWN:
503                                                 switch(vh->data[1]) {
504                                                 case 0x1:
505                                                         if (option_debug) 
506                                                                 ast_log(LOG_DEBUG, "Answered '%s'\n", ast->name);
507                                                         else if (option_verbose > 2) 
508                                                                 ast_verbose( VERBOSE_PREFIX_3 "Answered '%s'\n", ast->name);
509                                                         ast->state = AST_STATE_UP;
510                                                         return 0;
511                                                         break;
512                                                 default:
513                                                         ast_log(LOG_WARNING, "Unexpected 'unknown' frame type %d\n", vh->data[1]);
514                                                 }
515                                                 break;
516                                         case VOFR_SIGNAL_ON_HOOK:
517                                                 /* Ignore onhooks.  */
518                                                 break;
519                                         default:
520                                                 ast_log(LOG_WARNING, "Unexpected signal type %d\n", vh->data[0]);
521                                         }
522                                         break;
523                                 default:
524                                         ast_log(LOG_WARNING, "Unexpected data type %d\n", vh->dtype);
525                                 }
526                         }
527                 }
528         }
529         ast_log(LOG_WARNING, "Did not get acknowledged answer\n");
530         return -1;
531 }
532
533 static char vofr_2digit(char c)
534 {
535         if (c == 11)
536                 return '#';
537         else if (c == 10)
538                 return '*';
539         else if ((c < 10) && (c >= 0))
540                 return '0' + c;
541         else
542                 return '?';
543 }
544
545 static struct ast_frame  *vofr_read(struct ast_channel *ast)
546 {
547         int res;
548         char tone;
549         int timeout,x;
550         struct vofr_pvt *p = ast->pvt->pvt;
551         short *swapping;
552         struct ast_frame *fr = (struct ast_frame *)(p->buf);
553         struct vofr_hdr *vh = (struct vofr_hdr *)(p->buf + sizeof(struct ast_frame) + AST_FRIENDLY_OFFSET - sizeof(struct vofr_hdr));
554         /* Read into the right place in the buffer, in case we send this
555            as a voice frame. */
556         CHECK_BLOCKING(ast);
557 retry:
558         res = read(p->s, ((char *)vh)  - FR_API_MESS, 
559                                 G723_MAX_BUF - AST_FRIENDLY_OFFSET - sizeof(struct ast_frame) + sizeof(struct vofr_hdr) + FR_API_MESS);
560         if (res < 0) {
561                 /*  XXX HUGE BUG IN SANGOMA'S STACK: IT IGNORES O_NONBLOCK XXX */
562                 if (errno == EAGAIN) {
563                         fd_set fds;
564                         FD_ZERO(&fds);
565                         FD_SET(p->s, &fds);
566                         select(p->s + 1, &fds, NULL, NULL, NULL);
567                         goto retry;
568                 }
569                 ast->blocking = 0;
570                 ast_log(LOG_WARNING, "Read error on %s: %s (%d)\n", ast->name, strerror(errno));
571                 return NULL;
572         }
573         ast->blocking = 0;
574                 
575 #ifdef VOFRDUMPER
576         vofr_dump_packet((void *)(vh), res);
577 #endif
578         res -= FR_API_MESS;             
579         if (res < sizeof(struct vofr_hdr)) {
580                 ast_log(LOG_WARNING, "Nonsense frame on %s\n", ast->name);
581                 return NULL;
582         }
583         /* Some nice norms */
584         fr->datalen = 0;
585         fr->timelen = 0;
586         fr->data =  NULL;
587         fr->src = type;
588         fr->offset = 0;
589         fr->mallocd=0;
590         
591         /* Now, what we do depends on what we read */
592         switch(vh->dtype) {
593         case VOFR_TYPE_SIGNAL:
594                 switch(vh->data[0]) {
595                 case VOFR_SIGNAL_ON_HOOK:
596                         /* Hang up this line */
597                         if ((ast->state == AST_STATE_UP) || (p->ringgothangup)) {
598                                 return NULL;
599                         } else {
600                                 fr->frametype = AST_FRAME_NULL;
601                                 fr->subclass = 0;
602                                 p->ringgothangup=1;
603                         }
604                         break;
605                 case VOFR_SIGNAL_RING:
606                         ast->rings++;
607                         p->ringgothangup = 0;
608                         break;
609                 case VOFR_SIGNAL_UNKNOWN:
610                         switch(vh->data[1]) {
611                         case 0x1:
612                                 /* This is a little tricky, because it depends
613                                    on the context of what state we're in */
614                                 switch(ast->state) {
615                                 case AST_STATE_RINGING:
616                                         fr->frametype = AST_FRAME_CONTROL;
617                                         fr->subclass = AST_CONTROL_ANSWER;
618                                         ast->state = AST_STATE_UP;
619                                         break;
620                                 case AST_STATE_DOWN:
621                                 case AST_STATE_UP:
622                                         fr->frametype = AST_FRAME_NULL;
623                                         fr->subclass = 0;
624                                         break;
625                                 }
626                                 break;
627                         case 0x2:
628                                 /* Remote acknowledged off hook */
629                                 fr->frametype = AST_FRAME_CONTROL;
630                                 fr->subclass = AST_CONTROL_OFFHOOK;
631                                 ast->state = AST_STATE_OFFHOOK;
632                                 break;
633                         case 0x3:
634                                 /* Busy signal */
635                                 fr->frametype = AST_FRAME_CONTROL;
636                                 fr->subclass = AST_CONTROL_BUSY;
637                                 ast->state = AST_STATE_BUSY;
638                                 break;
639                         case 0x5:
640                                 /* Ringing -- acknowledged */
641                                 fr->frametype = AST_FRAME_CONTROL;
642                                 fr->subclass = AST_CONTROL_RINGING;
643                                 ast->state = AST_STATE_RINGING;
644                                 break;
645                         case 0x6:
646                                 /* Hang up detected.  Return NULL */
647                                 return NULL;
648                         default:
649                                 ast_log(LOG_WARNING, "Don't know what to do with 'unknown' signal '%d'\n", vh->data[1]);
650                                 fr->frametype = AST_FRAME_NULL;
651                                 fr->subclass = 0;
652                         }
653                         return fr;
654                         break;
655                 default:
656                         ast_log(LOG_WARNING, "Don't know what to do with signal '%d'\n", vh->data[0]);
657                 }
658                 break;
659         case VOFR_TYPE_DTMF:
660                 /* If it's a DTMF tone, then we want to wait until we don't get any more dtmf tones or
661                    the DTMF tone changes.  
662                        XXX Note: We will drop at least one frame here though XXX */
663                 
664                 tone = vofr_2digit(vh->data[0]);
665                 timeout = 50;
666                 do {
667                         if ((timeout = ast_waitfor(ast, timeout)) < 1)
668                                 break;
669                         CHECK_BLOCKING(ast);
670                         res = read(p->s, ((char *)vh)  - FR_API_MESS, 
671                                         G723_MAX_BUF - AST_FRIENDLY_OFFSET - sizeof(struct ast_frame) + sizeof(struct vofr_hdr) + FR_API_MESS);
672                         ast->blocking = 0;
673                         res -= FR_API_MESS;             
674                         if (res < sizeof(struct vofr_hdr *)) {
675                                 ast_log(LOG_WARNING, "Nonsense frame on %s\n", ast->name);
676                                 return NULL;
677                         }
678                         if (vh->dtype == VOFR_TYPE_DTMF) {
679                                 /* Reset the timeout */
680                                 timeout = 50;
681                                 if ((tone != vofr_2digit(vh->data[0])) )
682                                         /* Or not...  Something else now.. Just send our first frame */
683                                         break;
684                         }
685                         
686                 } while (timeout);
687                 fr->frametype = AST_FRAME_DTMF;
688                 fr->subclass = tone;
689                 fr->datalen = 0;
690                 fr->data = NULL;
691                 fr->offset = 0;
692                 return fr;
693         case VOFR_TYPE_VOICE:
694                 /* XXX Bug in the Adtran: Sometimes we don't know when calls are picked up, so if we
695                        get voice frames, go ahead and consider it answered even though it probably has
696                            not been answered XXX */
697                 if ((ast->state == AST_STATE_RINGING) || (ast->state == AST_STATE_DIALING))  {
698                         ast_log(LOG_DEBUG, "Adtran bug! (state = %d)\n", ast->state);
699                         fr->frametype = AST_FRAME_CONTROL;
700                         fr->subclass = AST_CONTROL_ANSWER;
701                         ast->state = AST_STATE_UP;
702                         return fr;
703                 } else if (ast->state !=  AST_STATE_UP) {
704                         ast_log(LOG_WARNING, "%s: Voice in weird state %d\n", ast->name, ast->state);
705                 }
706                 fr->frametype = AST_FRAME_VOICE;
707                 fr->subclass = AST_FORMAT_G723_1;
708                 fr->datalen = res - sizeof(struct vofr_hdr);
709                 fr->data = ((char *)vh) + sizeof(struct vofr_hdr);
710                 fr->src = type;
711                 /* XXX Byte swapping is a bug XXX */
712                 swapping = fr->data;
713                 for (x=0;x<fr->datalen/2;x++)
714                         swapping[x] = ntohs(swapping[x]);
715                 fr->offset = AST_FRIENDLY_OFFSET;
716                 /* Thirty ms of sound per frame */
717                 fr->timelen = 30;
718                 return fr;
719         default:
720                 ast_log(LOG_WARNING, "Don't know what to do with data type %d frames\n", vh->dtype);
721         }
722         /* If we don't know what it is, send a NULL frame */
723         fr->frametype = AST_FRAME_NULL;
724         fr->subclass = 0;
725         return fr;
726 }
727
728 static int vofr_write(struct ast_channel *ast, struct ast_frame *frame)
729 {
730         struct vofr_hdr *vh;
731         struct vofr_pvt *p = ast->pvt->pvt;
732         short *swapping;
733     int x;
734         char *start;
735         int res;
736         /* Write a frame of (presumably voice) data */
737         if (frame->frametype != AST_FRAME_VOICE) {
738                 ast_log(LOG_WARNING, "Don't know what to do with  frame type '%d'\n", frame->frametype);
739                 return -1;
740         }
741         if (frame->subclass != AST_FORMAT_G723_1) {
742                 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
743                 return -1;
744         }
745         /* If we get here, we have a voice frame of G.723.1 data.  First check to be
746            sure we have enough headroom for the vofr header.  If there isn't enough
747            headroom, we're lazy and just error out rather than copying it into the
748            output buffer, because applications should always leave AST_FRIENDLY_OFFSET
749            bytes just for this reason. */
750         if (frame->offset < sizeof(struct vofr_hdr) + FR_API_MESS) {
751                 ast_log(LOG_WARNING, "Frame source '%s' didn't provide a friendly enough offset\n", (frame->src ? frame->src : "**Unknown**"));
752                 return -1;
753         }
754         /* XXX Byte swapping is a bug XXX */
755         swapping = frame->data;
756         for (x=0;x<frame->datalen/2;x++)
757                 swapping[x] = ntohs(swapping[x]);
758         vh = (struct vofr_hdr *)(frame->data - sizeof(struct vofr_hdr));
759         /* Some versions of the API have some header mess that needs to be
760            zero'd out and acounted for..  */
761         start = ((void *)vh) - FR_API_MESS;
762         if (start)
763                 memset(start, 0, FR_API_MESS);
764         /* Now we fill in the vofr header */
765         vh->control = VOFR_CONTROL_VOICE;
766         vh->dtype = VOFR_TYPE_VOICE;
767         vh->vflags = VOFR_ROUTE_NONE;
768         vh->dlcih = p->dlcih;
769         vh->dlcil = p->dlcil;
770         vh->cid = p->cid;
771         vh->remid = VOFR_CARD_TYPE_ASTERISK;
772         vh->mod = VOFR_MODULATION_SINGLE;
773         res = vofr_xmit(p, start, 
774                                 VOFR_HDR_SIZE + frame->datalen + FR_API_MESS);
775         res -= FR_API_MESS;
776         /* XXX Byte swapping is a bug, but get it back to the right format XXX */
777         swapping = frame->data;
778         for (x=0;x<frame->datalen/2;x++)
779                 swapping[x] = htons(swapping[x]);
780         if (res != VOFR_HDR_SIZE + frame->datalen) {
781                 ast_log(LOG_WARNING, "Unable to write frame correctly\n");
782                 return -1;
783         }
784         return 0;
785 }
786
787 static int vofr_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
788 {
789         struct vofr_pvt *p = newchan->pvt->pvt;
790         if (p->owner != oldchan) {
791                 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
792                 return -1;
793         }
794         p->owner = newchan;
795         return 0;
796 }
797
798 static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
799 {
800         struct ast_channel *tmp;
801         tmp = ast_channel_alloc();
802         if (tmp) {
803 #ifdef OLD_SANGOMA_API
804                 snprintf(tmp->name, sizeof(tmp->name), "AdtranVoFR/%s", i->sa.spkt_device);
805 #else
806                 snprintf(tmp->name, sizeof(tmp->name), "AdtranVoFR/%s", i->sa.sll_device);
807 #endif
808                 tmp->type = type;
809                 tmp->fds[0] = i->s;
810                 /* Adtran VoFR supports only G723.1 format data.  G711 (ulaw) would be nice too */
811                 tmp->nativeformats = AST_FORMAT_G723_1;
812                 tmp->state = state;
813                 if (state == AST_STATE_RING)
814                         tmp->rings = 1;
815                 tmp->writeformat = AST_FORMAT_G723_1;
816                 tmp->readformat = AST_FORMAT_G723_1;
817                 tmp->pvt->pvt = i;
818                 tmp->pvt->send_digit = vofr_digit;
819                 tmp->pvt->call = vofr_call;
820                 tmp->pvt->hangup = vofr_hangup;
821                 tmp->pvt->answer = vofr_answer;
822                 tmp->pvt->read = vofr_read;
823                 tmp->pvt->write = vofr_write;
824                 tmp->pvt->fixup = vofr_fixup;
825                 if (strlen(i->language))
826                         strncpy(tmp->language, i->language, sizeof(tmp->language));
827                 i->owner = tmp;
828                 ast_pthread_mutex_lock(&usecnt_lock);
829                 usecnt++;
830                 ast_pthread_mutex_unlock(&usecnt_lock);
831                 ast_update_use_count();
832                 strncpy(tmp->context, i->context, sizeof(tmp->context));
833                 if (state != AST_STATE_DOWN) {
834                         if (ast_pbx_start(tmp)) {
835                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
836                                 ast_hangup(tmp);
837                                 tmp = NULL;
838                         }
839                 }
840         } else
841                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
842         return tmp;
843 }
844
845 static int vofr_mini_packet(struct vofr_pvt *i, struct vofr_hdr *pkt, int len)
846 {
847         /* Here, we're looking for rings or off hooks -- signals that
848            something is about to happen and we need to start the 
849            PBX thread */
850         switch(pkt->dtype) {
851         case VOFR_TYPE_SIGNAL:
852                 switch(pkt->data[0]) {
853                 case VOFR_SIGNAL_RING:
854                         /* If we get a RING, we definitely want to start a new thread */
855                         if (!i->owner) {
856                                 i->ringgothangup = 0;
857                                 vofr_new(i, AST_STATE_RING);
858                         } else
859                                 ast_log(LOG_WARNING, "Got a ring, but there's an owner?\n");
860                         break;
861                 case VOFR_SIGNAL_OFF_HOOK:
862                         /* Network termination, go off hook */
863 #if 0
864                         ast_log(LOG_DEBUG, "Off hook\n");
865 #endif
866                         vofr_xmit_signal(i, 0x10, 2);
867                         if (!i->owner)
868                                 vofr_new(i, AST_STATE_UP);
869                         else
870                                 ast_log(LOG_WARNING, "Got an offhook, but there's an owner?\n");
871                         break;
872                 case VOFR_SIGNAL_ON_HOOK:
873                         break;
874                 case VOFR_SIGNAL_UNKNOWN:
875                         switch(pkt->data[1]) {
876                         case 0x1:
877                                 /* ignore */
878                                 break;
879                         case 0x6:
880                                 /* A remote hangup request */
881                                 if (option_debug)
882                                         ast_log(LOG_DEBUG, "Sending hangup reply\n");
883                                 send_hangup(i);
884                                 break;
885                         default:
886                                 ast_log(LOG_WARNING, "Unexected 'unknown' signal '%d'\n", pkt->data[1]);
887                         }
888                         break;
889                 default:
890                         ast_log(LOG_DEBUG, "Unknown signal type '%d'\n", pkt->data[0]);
891                 }                       
892                 break;
893         case VOFR_TYPE_VOICE:
894                 break;
895         default:
896                 ast_log(LOG_DEBUG, "Unknown packet type '%d'\n", pkt->dtype);
897         }
898         return 0;
899 }
900
901 static void *do_monitor(void *data)
902 {
903         fd_set rfds;
904         int n, res;
905         struct vofr_pvt *i;
906         /* This thread monitors all the frame relay interfaces which are not yet in use
907            (and thus do not have a separate thread) indefinitely */
908         /* From here on out, we die whenever asked */
909 #if 0
910         if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
911                 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
912                 return NULL;
913         }
914 #endif
915         for(;;) {
916                 /* Don't let anybody kill us right away.  Nobody should lock the interface list
917                    and wait for the monitor list, but the other way around is okay. */
918                 if (ast_pthread_mutex_lock(&monlock)) {
919                         ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
920                         return NULL;
921                 }
922                 /* Lock the interface list */
923                 if (ast_pthread_mutex_lock(&iflock)) {
924                         ast_log(LOG_ERROR, "Unable to grab interface lock\n");
925                         ast_pthread_mutex_unlock(&monlock);
926                         return NULL;
927                 }
928                 /* Build the stuff we're going to select on, that is the socket of every
929                    vofr_pvt that does not have an associated owner channel */
930                 n = -1;
931                 FD_ZERO(&rfds);
932                 i = iflist;
933                 while(i) {
934                         if (FD_ISSET(i->s, &rfds)) 
935 #ifdef OLD_SANGOMA_API
936                                 ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->s, i->sa.spkt_device);
937 #else
938                                 ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->s, i->sa.sll_device);
939 #endif
940                         if (!i->owner) {
941                                 /* This needs to be watched, as it lacks an owner */
942                                 FD_SET(i->s, &rfds);
943                                 if (i->s > n)
944                                         n = i->s;
945                         }
946                         i = i->next;
947                 }
948                 /* Okay, now that we know what to do, release the interface lock */
949                 ast_pthread_mutex_unlock(&iflock);
950                 
951                 /* And from now on, we're okay to be killed, so release the monitor lock as well */
952                 ast_pthread_mutex_unlock(&monlock);
953                 pthread_testcancel();
954                 /* Wait indefinitely for something to happen */
955                 res = select(n + 1, &rfds, NULL, NULL, NULL);
956                 pthread_testcancel();
957                 /* Okay, select has finished.  Let's see what happened.  */
958                 if (res < 0) {
959                         if ((errno != EAGAIN) && (errno != EINTR))
960                                 ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
961                         continue;
962                 }
963                 /* Alright, lock the interface list again, and let's look and see what has
964                    happened */
965                 if (ast_pthread_mutex_lock(&iflock)) {
966                         ast_log(LOG_WARNING, "Unable to lock the interface list\n");
967                         continue;
968                 }
969                 i = iflist;
970                 while(i) {
971                         if (FD_ISSET(i->s, &rfds)) {
972                                 if (i->owner) {
973 #ifdef OLD_SANGOMA_API
974                                         ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d, %s)...\n", i->s, i->sa.spkt_device);
975 #else
976                                         ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d, %s)...\n", i->s, i->sa.sll_device);
977 #endif
978                                         continue;
979                                 }
980                                 res = read(i->s, i->buf, sizeof(i->buf));
981                                 res -= FR_API_MESS;
982 #ifdef VOFRDUMPER
983                                 vofr_dump_packet(i->hdr, res);
984 #endif
985                                 vofr_mini_packet(i, i->hdr, res);
986                         }
987                         i=i->next;
988                 }
989                 ast_pthread_mutex_unlock(&iflock);
990         }
991         /* Never reached */
992         return NULL;
993         
994 }
995
996 static int restart_monitor(void)
997 {
998         /* If we're supposed to be stopped -- stay stopped */
999         if (monitor_thread == -2)
1000                 return 0;
1001         if (ast_pthread_mutex_lock(&monlock)) {
1002                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
1003                 return -1;
1004         }
1005         if (monitor_thread == pthread_self()) {
1006                 ast_pthread_mutex_unlock(&monlock);
1007                 ast_log(LOG_WARNING, "Cannot kill myself\n");
1008                 return -1;
1009         }
1010         if (monitor_thread) {
1011                 /* Wake up the thread */
1012                 pthread_kill(monitor_thread, SIGURG);
1013         } else {
1014                 /* Start a new monitor */
1015                 if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
1016                         ast_pthread_mutex_unlock(&monlock);
1017                         ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
1018                         return -1;
1019                 }
1020         }
1021         ast_pthread_mutex_unlock(&monlock);
1022         return 0;
1023 }
1024
1025 static struct vofr_pvt *mkif(char *type, char *iface)
1026 {
1027         /* Make a vofr_pvt structure for this interface */
1028         struct vofr_pvt *tmp;
1029         int sndbuf = 4096;
1030
1031         tmp = malloc(sizeof(struct vofr_pvt));
1032         if (tmp) {
1033
1034                 /* Allocate a packet socket */
1035 #ifdef OLD_SANGOMA_API
1036                 tmp->s = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
1037 #else
1038                 /* Why the HELL does Sangoma change their API every damn time
1039                    they make a new driver release?!?!?!  Leave it the hell
1040                    alone this time.  */
1041                 tmp->s = socket(AF_WANPIPE, SOCK_RAW, 0);
1042 #endif          
1043
1044                 if (tmp->s < 0) {
1045                         ast_log(LOG_ERROR, "Unable to create socket: %s\n", strerror(errno));
1046                         free(tmp);
1047                         return NULL;
1048                 }
1049
1050 #ifdef OLD_SANGOMA_API
1051                 /* Prepare sockaddr for binding */
1052                 memset(&tmp->sa, 0, sizeof(tmp->sa));
1053                 strncpy(tmp->sa.spkt_device, iface, sizeof(tmp->sa.spkt_device));
1054                 tmp->sa.spkt_protocol = htons(0x16);
1055                 tmp->sa.spkt_family = AF_PACKET;
1056                 if (bind(tmp->s, (struct sockaddr *)&tmp->sa, sizeof(struct sockaddr))) {
1057 #else
1058                 /* Prepare sockaddr for binding */
1059                 memset(&tmp->sa, 0, sizeof(tmp->sa));
1060                 tmp->sa.sll_family = AF_WANPIPE;
1061                 tmp->sa.sll_protocol = htons(ETH_P_IP);
1062                 strncpy(tmp->sa.sll_device, iface, sizeof(tmp->sa.sll_device));
1063                 strncpy(tmp->sa.sll_card, "wanpipe1", sizeof(tmp->sa.sll_card));
1064                 tmp->sa.sll_ifindex = 0;
1065                 if (bind(tmp->s, (struct sockaddr *)&tmp->sa, sizeof(struct wan_sockaddr_ll))) {
1066 #endif          
1067                 /* Bind socket to specific interface */
1068 #ifdef OLD_SANGOMA_API
1069                         ast_log(LOG_ERROR, "Unable to bind to '%s': %s\n", tmp->sa.spkt_device, 
1070 #else
1071                         ast_log(LOG_ERROR, "Unable to bind to '%s': %s\n", tmp->sa.sll_device, 
1072 #endif
1073                                                                                 strerror(errno));
1074                         free(tmp);
1075                         return NULL;
1076                 }
1077                 
1078                 /* Set magic send buffer size */
1079                 if (setsockopt(tmp->s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
1080                         ast_log(LOG_ERROR, "Unable to set send buffer size to %d: %s\n", sndbuf, strerror(errno));
1081                         free(tmp);
1082                         return NULL;
1083                 }
1084                 tmp->owner =  NULL;
1085                 tmp->hdr = (struct vofr_hdr *)(tmp->buf + FR_API_MESS);
1086                 tmp->ohdr = (struct vofr_hdr *)(tmp->obuf + FR_API_MESS);
1087                 tmp->dlcil = 0;
1088                 tmp->dlcih = 0;
1089                 tmp->cid = 1;
1090                 tmp->ringgothangup = 0;
1091                 strncpy(tmp->language, language, sizeof(tmp->language));
1092                 strncpy(tmp->context, context, sizeof(tmp->context));
1093                 /* User terminations are game for outgoing connections */
1094                 if (!strcasecmp(type, "user")) 
1095                         tmp->outgoing = 1;
1096                 else
1097                         tmp->outgoing = 0;
1098                 tmp->next = NULL;
1099                 /* Hang it up to be sure it's good */
1100                 send_hangup(tmp);
1101                 
1102         }
1103         return tmp;
1104 }
1105
1106 static struct ast_channel *vofr_request(char *type, int format, void *data)
1107 {
1108         int oldformat;
1109         struct vofr_pvt *p;
1110         struct ast_channel *tmp = NULL;
1111         /* We can only support G.723.1 formatted frames, but we should never
1112            be asked to support anything else anyway, since we've published
1113            our capabilities when we registered. */
1114         oldformat = format;
1115         format &= AST_FORMAT_G723_1;
1116         if (!format) {
1117                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format);
1118                 return NULL;
1119         }
1120         /* Search for an unowned channel */
1121         if (ast_pthread_mutex_lock(&iflock)) {
1122                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
1123                 return NULL;
1124         }
1125         p = iflist;
1126         while(p) {
1127                 if (!p->owner && p->outgoing) {
1128                         tmp = vofr_new(p, AST_STATE_DOWN);
1129                         break;
1130                 }
1131                 p = p->next;
1132         }
1133         ast_pthread_mutex_unlock(&iflock);
1134         restart_monitor();
1135         return tmp;
1136 }
1137
1138 int load_module()
1139 {
1140         struct ast_config *cfg;
1141         struct ast_variable *v;
1142         struct vofr_pvt *tmp;
1143         cfg = ast_load(config);
1144
1145         /* We *must* have a config file otherwise stop immediately */
1146         if (!cfg) {
1147                 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
1148                 return -1;
1149         }
1150         if (ast_pthread_mutex_lock(&iflock)) {
1151                 /* It's a little silly to lock it, but we mind as well just to be sure */
1152                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
1153                 return -1;
1154         }
1155         v = ast_variable_browse(cfg, "interfaces");
1156         while(v) {
1157                 /* Create the interface list */
1158                 if (!strcasecmp(v->name, "user") ||
1159                         !strcasecmp(v->name, "network")) {
1160                                 tmp = mkif(v->name, v->value);
1161                                 if (tmp) {
1162                                         tmp->next = iflist;
1163                                         iflist = tmp;
1164                                 } else {
1165                                         ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
1166                                         ast_destroy(cfg);
1167                                         ast_pthread_mutex_unlock(&iflock);
1168                                         unload_module();
1169                                         return -1;
1170                                 }
1171                 } else if (!strcasecmp(v->name, "context")) {
1172                         strncpy(context, v->value, sizeof(context));
1173                 } else if (!strcasecmp(v->name, "language")) {
1174                         strncpy(language, v->value, sizeof(language));
1175                 }
1176                 v = v->next;
1177         }
1178         ast_pthread_mutex_unlock(&iflock);
1179         /* Make sure we can register our AdtranVoFR channel type */
1180         if (ast_channel_register(type, tdesc, AST_FORMAT_G723_1, vofr_request)) {
1181                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
1182                 ast_destroy(cfg);
1183                 unload_module();
1184                 return -1;
1185         }
1186         ast_destroy(cfg);
1187         /* And start the monitor for the first time */
1188         restart_monitor();
1189         return 0;
1190 }
1191
1192 int unload_module()
1193 {
1194         struct vofr_pvt *p, *pl;
1195         /* First, take us out of the channel loop */
1196         ast_channel_unregister(type);
1197         if (!ast_pthread_mutex_lock(&iflock)) {
1198                 /* Hangup all interfaces if they have an owner */
1199                 p = iflist;
1200                 while(p) {
1201                         if (p->owner)
1202                                 ast_softhangup(p->owner);
1203                         p = p->next;
1204                 }
1205                 iflist = NULL;
1206                 ast_pthread_mutex_unlock(&iflock);
1207         } else {
1208                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1209                 return -1;
1210         }
1211         if (!ast_pthread_mutex_lock(&monlock)) {
1212                 if (monitor_thread) {
1213                         pthread_cancel(monitor_thread);
1214                         pthread_kill(monitor_thread, SIGURG);
1215                         pthread_join(monitor_thread, NULL);
1216                 }
1217                 monitor_thread = -2;
1218                 ast_pthread_mutex_unlock(&monlock);
1219         } else {
1220                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1221                 return -1;
1222         }
1223
1224         if (!ast_pthread_mutex_lock(&iflock)) {
1225                 /* Destroy all the interfaces and free their memory */
1226                 p = iflist;
1227                 while(p) {
1228                         /* Close the socket, assuming it's real */
1229                         if (p->s > -1)
1230                                 close(p->s);
1231                         pl = p;
1232                         p = p->next;
1233                         /* Free associated memory */
1234                         free(pl);
1235                 }
1236                 iflist = NULL;
1237                 ast_pthread_mutex_unlock(&iflock);
1238         } else {
1239                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1240                 return -1;
1241         }
1242                 
1243         return 0;
1244 }
1245
1246 int usecount()
1247 {
1248         int res;
1249         ast_pthread_mutex_lock(&usecnt_lock);
1250         res = usecnt;
1251         ast_pthread_mutex_unlock(&usecnt_lock);
1252         return res;
1253 }
1254
1255 char *key()
1256 {
1257         return ASTERISK_GPL_KEY;
1258 }
1259
1260 char *description()
1261 {
1262         return desc;
1263 }
1264