Version 0.1.7 from FTP
[asterisk/asterisk.git] / channels / chan_tor.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Tormenta T1 Card (via Zapata library) support 
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 <asterisk/file.h>
25 #include <asterisk/ulaw.h>
26 #include <asterisk/callerid.h>
27 #include <sys/signal.h>
28 #include <sys/select.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <sys/ioctl.h>
33 #include <linux/tor.h>
34 #include <zap.h>
35 #include <math.h>
36 #include <tonezone.h>
37
38 static char *desc = "Tormenta (Zapata) Channelized T1 Driver";
39 static char *type = "Tor";
40 static char *tdesc = "Tormenta T1 Driver";
41 static char *config = "tormenta.conf";
42
43 #define SIG_EM          0x1
44 #define SIG_EMWINK      0x11
45 #define SIG_FEATD       0X21
46 #define SIG_FXSLS       0x2
47 #define SIG_FXSGS       0x3
48 #define SIG_FXSKS       0x4
49 #define SIG_FXOLS       0x5
50 #define SIG_FXOGS       0x6
51 #define SIG_FXOKS       0x7
52
53 #define tor_STATE_DOWN 0
54
55 static char context[AST_MAX_EXTENSION] = "default";
56 static char callerid[256] = "";
57
58 /* Keep certain dial patterns from turning off dialtone */
59 #define AST_MAX_DIAL_PAT 32
60
61 static char keepdialpat[AST_MAX_DIAL_PAT][10];
62 static int dialpats = 0;
63
64 static char language[MAX_LANGUAGE] = "";
65
66 static int use_callerid = 1;
67
68 static int cur_signalling = -1;
69
70 static int cur_group = 0;
71
72 static int immediate = 0;
73
74 static int stripmsd = 0;
75
76 /* Wait up to 16 seconds for first digit (FXO logic) */
77 static int firstdigittimeout = 16000;
78
79 /* How long to wait for following digits (FXO logic) */
80 static int gendigittimeout = 8000;
81
82 static int usecnt =0;
83 static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
84
85 /* Protect the interface list (of tor_pvt's) */
86 static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
87
88 /* Protect the monitoring thread, so only one process can kill or start it, and not
89    when it's doing something critical. */
90 static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
91
92 /* This is the thread for the monitor which checks for input on the channels
93    which are not currently in use.  */
94 static pthread_t monitor_thread = 0;
95
96 static int restart_monitor(void);
97
98 static inline int tor_get_event(int fd)
99 {
100         /* Avoid the silly tor_getevent which ignores a bunch of events */
101         int j;
102         if (ioctl(fd, TOR_GETEVENT, &j) == -1) return -1;
103         return j;
104 }
105
106 static inline int tor_wait_event(int fd)
107 {
108         /* Avoid the silly tor_waitevent which ignores a bunch of events */
109         int i,j=0;
110         i = TOR_IOMUX_SIGEVENT;
111         if (ioctl(fd, TOR_IOMUX, &i) == -1) return -1;
112         if (ioctl(fd, TOR_GETEVENT, &j) == -1) return -1;
113         return j;
114 }
115
116 /* Chunk size to read -- we use the same size as the chunks that the zapata library uses.  */   
117 #define READ_SIZE 204
118
119 static struct tor_pvt {
120         ZAP *z;
121         struct ast_channel *owner;      /* Our owner (if applicable) */
122         int sig;                                        /* Signalling style */
123         struct tor_pvt *next;                   /* Next channel in list */
124         char context[AST_MAX_EXTENSION];
125         char language[MAX_LANGUAGE];
126         char callerid[AST_MAX_EXTENSION];
127         char dtmfq[AST_MAX_EXTENSION];
128         struct ast_frame f;
129         short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
130         int group;
131         int state;                                              /* Perhaps useful state info */
132         int immediate;                          /* Answer before getting digits? */
133         int channel;                            /* Channel Number */
134         int ringgothangup;                              /* Have we received exactly one hangup after a ring */
135         int dialing;
136         int use_callerid;                       /* Whether or not to use caller id on this channel */
137         unsigned char *cidspill;
138         int cidpos;
139         int cidlen;
140         int stripmsd;
141         DIAL_OPERATION dop;
142 } *iflist = NULL;
143
144 static int tor_digit(struct ast_channel *ast, char digit)
145 {
146         DIAL_OPERATION zo;
147         struct tor_pvt *p;
148         int res;
149         zo.op = TOR_DIAL_OP_APPEND;
150         zo.dialstr[0] = 'T';
151         zo.dialstr[1] = digit;
152         zo.dialstr[2] = 0;
153         p = ast->pvt->pvt;
154         if ((res = ioctl(zap_fd(p->z), TOR_DIAL, &zo)))
155                 ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
156         else
157                 p->dialing = 1;
158         
159         return res;
160 }
161
162 static char *events[] = {
163         "No event",
164         "On hook",
165         "Ring/Answered",
166         "Wink/Flash",
167         "Alarm",
168         "No more alarm",
169                 "HDLC Abort",
170                 "HDLC Overrun",
171                 "HDLC Bad FCS",
172                 "Dial Complete",
173                 "Ringer On",
174                 "Ringer Off",
175                 "Hook Transition Complete"
176 };
177  
178 static char *event2str(int event)
179 {
180         static char buf[256];
181         if ((event < 13) && (event > -1))
182                 return events[event];
183         sprintf(buf, "Event %d", event);
184         return buf;
185 }
186
187 static char *sig2str(int sig)
188 {
189         static char buf[256];
190         switch(sig) {
191         case SIG_EM:
192                 return "E & M Immediate";
193         case SIG_EMWINK:
194                 return "E & M Wink";
195         case SIG_FEATD:
196                 return "Feature Group D";
197         case SIG_FXSLS:
198                 return "FXS Loopstart";
199         case SIG_FXSGS:
200                 return "FXS Groundstart";
201         case SIG_FXSKS:
202                 return "FXS Kewlstart";
203         case SIG_FXOLS:
204                 return "FXO Loopstart";
205         case SIG_FXOGS:
206                 return "FXO Groundstart";
207         case SIG_FXOKS:
208                 return "FXO Kewlstart";
209         default:
210                 snprintf(buf, sizeof(buf), "Unknown signalling %d\n", sig);
211                 return buf;
212         }
213 }
214
215 static int set_actual_gain(int fd, int chan, float rxgain, float txgain)
216 {
217         struct  tor_gains g;
218         float ltxgain;
219         float lrxgain;
220         int j,k;
221         g.chan = chan;
222           /* caluculate linear value of tx gain */
223         ltxgain = pow(10.0,txgain / 20.0);
224           /* caluculate linear value of rx gain */
225         lrxgain = pow(10.0,rxgain / 20.0);
226         for (j=0;j<256;j++) {
227                 k = (int)(((float)ast_mulaw[j]) * lrxgain);
228                 if (k > 32767) k = 32767;
229                 if (k < -32767) k = -32767;
230                 g.rxgain[j] = ast_lin2mu[k + 32768];
231                 k = (int)(((float)ast_mulaw[j]) * ltxgain);
232                 if (k > 32767) k = 32767;
233                 if (k < -32767) k = -32767;
234                 g.txgain[j] = ast_lin2mu[k + 32768];
235         }
236                 
237           /* set 'em */
238         return(ioctl(fd,TOR_SETGAINS,&g));
239 }
240 static inline int tor_set_hook(int fd, int hs)
241 {
242         int x, res;
243         x = hs;
244         res = ioctl(fd, TOR_HOOK, &x);
245         if (res < 0) 
246                 ast_log(LOG_WARNING, "tor hook failed: %s\n", strerror(errno));
247         return res;
248 }
249
250
251 static int send_callerid(struct tor_pvt *p)
252 {
253         /* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
254         int res;
255         while(p->cidpos < p->cidlen) {
256                 res = write(zap_fd(p->z), p->cidspill + p->cidpos, p->cidlen - p->cidpos);
257                 if (res < 0) {
258                         if (errno == EAGAIN)
259                                 return 0;
260                         else {
261                                 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
262                                 return -1;
263                         }
264                 }
265                 if (!res)
266                         return 0;
267                 p->cidpos += res;
268         }
269         free(p->cidspill);
270         p->cidspill = 0;
271         return 0;
272 }
273                                                                                 
274 static int tor_call(struct ast_channel *ast, char *dest, int timeout)
275 {
276         struct tor_pvt *p = ast->pvt->pvt;
277         int x, res;
278         char *c, *n, *l;
279         char callerid[256];
280         if ((ast->state != AST_STATE_DOWN) && (ast->state != AST_STATE_RESERVED)) {
281                 ast_log(LOG_WARNING, "tor_call called on %s, neither down nor reserved\n", ast->name);
282                 return -1;
283         }
284         switch(p->sig) {
285         case SIG_FXOLS:
286         case SIG_FXOGS:
287         case SIG_FXOKS:
288                 if (p->use_callerid) {
289                         /* Generate the Caller-ID spill if desired */
290                         if (p->cidspill) {
291                                 ast_log(LOG_WARNING, "cidspill already exists??\n");
292                                 free(p->cidspill);
293                         }
294                         p->cidspill = malloc(MAX_CALLERID_SIZE);
295                         if (p->cidspill) {
296                                 p->cidlen = ast_callerid_generate(p->cidspill, ast->callerid);
297                                 p->cidpos = 0;
298                                 send_callerid(p);
299                         } else
300                                 ast_log(LOG_WARNING, "Unable to generate CallerID spill\n");
301                 }
302                 x = TOR_RING;
303                 if (ioctl(zap_fd(p->z), TOR_HOOK, &x) && (errno != EINPROGRESS)) {
304                         ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
305                         return -1;
306                 }
307                 ast->state = AST_STATE_RINGING;
308                 break;
309         case SIG_FXSLS:
310         case SIG_FXSGS:
311         case SIG_FXSKS:
312         case SIG_EMWINK:
313         case SIG_EM:
314         case SIG_FEATD:
315                 c = strchr(dest, '/');
316                 if (c)
317                         c++;
318                 else
319                         c = dest;
320                 if (strlen(c) < p->stripmsd) {
321                         ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
322                         return -1;
323                 }
324                 x = TOR_START;
325                 /* Start the trunk */
326                 res = ioctl(zap_fd(p->z), TOR_HOOK, &x);
327                 if (res < 0) {
328                         if (errno != EINPROGRESS) {
329                                 ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
330                                 return -1;
331                         }
332                 }
333                 ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
334                 p->dop.op = TOR_DIAL_OP_REPLACE;
335                 if (p->sig == SIG_FEATD) {
336                         if (ast->callerid) {
337                                 strncpy(callerid, ast->callerid, sizeof(callerid));
338                                 ast_callerid_parse(callerid, &n, &l);
339                                 printf("Name: %s, number: %s\n", n, l);
340                                 if (l) {
341                                         ast_shrink_phone_number(l);
342                                         if (!ast_isphonenumber(l))
343                                                 l = NULL;
344                                 }
345                         } else
346                                 l = NULL;
347                         if (l) 
348                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c + p->stripmsd);
349                         else
350                                 snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c + p->stripmsd);
351                 } else 
352                         snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", c + p->stripmsd);
353                 if (!res) {
354                         if (ioctl(zap_fd(p->z), TOR_DIAL, &p->dop)) {
355                                 x = TOR_ONHOOK;
356                                 ioctl(zap_fd(p->z), TOR_HOOK, &x);
357                                 ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
358                                 return -1;
359                         }
360                 } else
361                         ast_log(LOG_DEBUG, "Deferring dialing...\n");
362                 p->dialing = 1;
363                 ast->state = AST_STATE_DIALING;
364                 break;
365         default:
366                 ast_log(LOG_DEBUG, "not yet implemented\n");
367                 return -1;
368         }
369         return 0;
370 }
371
372 static int tor_hangup(struct ast_channel *ast)
373 {
374         int res;
375         struct tor_pvt *p = ast->pvt->pvt;
376         TOR_PARAMS par;
377         if (option_debug)
378                 ast_log(LOG_DEBUG, "tor_hangup(%s)\n", ast->name);
379         if (!ast->pvt->pvt) {
380                 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
381                 return 0;
382         }
383         res = tor_set_hook(zap_fd(p->z), TOR_ONHOOK);
384         if (res < 0) {
385                 ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
386                 return -1;
387         }
388         switch(p->sig) {
389         case SIG_FXOGS:
390         case SIG_FXOLS:
391         case SIG_FXOKS:
392                 res = ioctl(zap_fd(p->z), TOR_GET_PARAMS, &par);
393                 if (!res) {
394                         /* If they're off hook, try playing congestion */
395                         if (par.rxisoffhook)
396                                 tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
397                 }
398                 break;
399         default:
400         }
401         ast->state = AST_STATE_DOWN;
402         p->owner = NULL;
403         p->ringgothangup = 0;
404         if (p->cidspill)
405                 free(p->cidspill);
406         p->cidspill = NULL;
407         pthread_mutex_lock(&usecnt_lock);
408         usecnt--;
409         if (usecnt < 0) 
410                 ast_log(LOG_WARNING, "Usecnt < 0???\n");
411         pthread_mutex_unlock(&usecnt_lock);
412         ast_update_use_count();
413         if (option_verbose > 2) 
414                 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
415         ast->pvt->pvt = NULL;
416         ast->state = AST_STATE_DOWN;
417         restart_monitor();
418         return 0;
419 }
420
421 static int tor_answer(struct ast_channel *ast)
422 {
423         struct tor_pvt *p = ast->pvt->pvt;
424         ast->state = AST_STATE_UP;
425         switch(p->sig) {
426         case SIG_FXSLS:
427         case SIG_FXSGS:
428         case SIG_FXSKS:
429         case SIG_EM:
430         case SIG_EMWINK:
431         case SIG_FEATD:
432         case SIG_FXOLS:
433         case SIG_FXOGS:
434         case SIG_FXOKS:
435                 /* Pick up the line */
436                 ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
437                 return tor_set_hook(zap_fd(p->z), TOR_OFFHOOK);
438                 break;
439                 /* Nothing */
440                 break;
441         default:
442                 ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
443                 return -1;
444         }
445         return 0;
446 }
447
448 static int bridge_cleanup(struct tor_pvt *p0, struct tor_pvt *p1)
449 {
450         struct tor_confinfo c;
451         int res;
452         c.chan = 0;
453         c.confno = 0;
454         c.confmode = TOR_CONF_NORMAL;
455         res = ioctl(zap_fd(p0->z), TOR_SETCONF, &c);
456         if (res) {
457                 ast_log(LOG_WARNING, "ioctl(TOR_SETCONF) failed on channel %d: %s\n", p0->channel, strerror(errno));
458                 return -1;
459         }
460         c.chan = 0;
461         c.confno = 0;
462         c.confmode = TOR_CONF_NORMAL;
463         res = ioctl(zap_fd(p1->z), TOR_SETCONF, &c);
464         if (res) {
465                 ast_log(LOG_WARNING, "ioctl(TOR_SETCONF) failed on channel %d: %s\n", p1->channel, strerror(errno));
466                 return -1;
467         }
468         return 0;
469 }
470
471
472 static int tor_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
473 {
474         /* Do a quickie conference between the two channels and wait for something to happen */
475         struct tor_pvt *p0 = c0->pvt->pvt;
476         struct tor_pvt *p1 = c1->pvt->pvt;
477         struct ast_channel *who, *cs[3];
478         struct ast_frame *f;
479         struct tor_confinfo c;
480         int res;
481         int to = -1;
482         /* Put the first channel in a unique conference */
483         c.chan = 0;
484         c.confno = p1->channel;
485         c.confmode = TOR_CONF_MONITOR;
486         
487         /* Stop any playing */
488         tone_zone_play_tone(zap_fd(p0->z),      -1);
489         res = ioctl(zap_fd(p0->z), TOR_SETCONF, &c);
490         if (res) {
491                 ast_log(LOG_WARNING, "ioctl(TOR_SETCONF) failed on channel %s: %s\n", c0->name, strerror(errno));
492                 bridge_cleanup(p0, p1);
493                 return -1;
494         }
495         if (option_debug)
496                 ast_log(LOG_DEBUG, "Channel %d got put on conference %d\n", c.chan, c.confno);
497
498         /* Put the other channel on the same conference */
499         c.chan = 0;
500         c.confno = p0->channel;
501         res = ioctl(zap_fd(p1->z), TOR_SETCONF, &c);
502         if (res) {
503                 ast_log(LOG_WARNING, "ioctl(TOR_SETCONF) failed on channel %s: %s\n", c0->name, strerror(errno));
504                 bridge_cleanup(p0, p1);
505                 return -1;
506         }
507         if (option_debug)
508                 ast_log(LOG_DEBUG, "Channel %d got put on conference %d\n", c.chan, c.confno);
509
510         for (;;) {
511                 cs[0] = c0;
512                 cs[1] = c1;
513                 who = ast_waitfor_n(cs, 2, &to);
514                 if (!who) {
515                         ast_log(LOG_WARNING, "Nobody there??\n");
516                         continue;
517                 }
518                 f = ast_read(who);
519                 if (!f) {
520                         *fo = NULL;
521                         *rc = who;
522                         bridge_cleanup(p0, p1);
523                         return 0;
524                 }
525                 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
526                         *fo = f;
527                         *rc = who;
528                         bridge_cleanup(p0, p1);
529                         return 0;
530                 }
531                 if ((f->frametype == AST_FRAME_VOICE) ||
532                         (f->frametype == AST_FRAME_TEXT) ||
533                         (f->frametype == AST_FRAME_VIDEO) || 
534                         (f->frametype == AST_FRAME_IMAGE) ||
535                         (f->frametype == AST_FRAME_DTMF)) {
536                         if ((f->frametype == AST_FRAME_DTMF) && (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
537                                 if ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
538                                         *rc = c0;
539                                         *fo = f;
540                                         bridge_cleanup(p0, p1);
541                                         return 0;
542                                 } else
543                                 if ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)) {
544                                         *rc = c1;
545                                         *fo = f;
546                                         bridge_cleanup(p0, p1);
547                                         return 0;
548                                 }
549                         }
550                         ast_frfree(f);
551                 } else
552                         ast_frfree(f);
553                 /* Swap who gets priority */
554                 cs[2] = cs[0];
555                 cs[0] = cs[1];
556                 cs[1] = cs[2];
557         }
558                 
559         return 0;
560 }
561
562 struct ast_frame *tor_handle_event(struct ast_channel *ast)
563 {
564         int res;
565         struct tor_pvt *p = ast->pvt->pvt;
566         p->f.frametype = AST_FRAME_NULL;
567         p->f.datalen = 0;
568         p->f.timelen = 0;
569         p->f.mallocd = 0;
570         p->f.offset = 0;
571         p->f.src = "tor_handle_event";
572         p->f.data = NULL;
573         res = tor_get_event(zap_fd(p->z));
574         ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d\n", event2str(res), res, p->channel);
575         switch(res) {
576                 case TOR_EVENT_DIALCOMPLETE:
577                         p->dialing = 0;
578                         if (ast->state == AST_STATE_DIALING) {
579 #if 0
580                                 ast->state = AST_STATE_RINGING;
581 #else
582                                 ast->state = AST_STATE_UP;
583                                 p->f.frametype = AST_FRAME_CONTROL;
584                                 p->f.subclass = AST_CONTROL_ANSWER;
585 #endif                          
586                         }
587                         break;
588                 case TOR_EVENT_ONHOOK:
589                         return NULL;
590                 case TOR_EVENT_RINGOFFHOOK:
591                         switch(p->sig) {
592                         case SIG_FXOLS:
593                         case SIG_FXOGS:
594                         case SIG_FXOKS:
595                                 switch(ast->state) {
596                                 case AST_STATE_RINGING:
597                                         ast->state = AST_STATE_UP;
598                                         p->f.frametype = AST_FRAME_CONTROL;
599                                         p->f.subclass = AST_CONTROL_ANSWER;
600                                         /* Make sure it stops ringing */
601                                         tor_set_hook(zap_fd(p->z), TOR_OFFHOOK);
602                                         ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
603                                         if (p->cidspill) {
604                                                 /* Cancel any running CallerID spill */
605                                                 free(p->cidspill);
606                                                 p->cidspill = NULL;
607                                         }
608                                         return &p->f;
609                                 case AST_STATE_DOWN:
610                                         ast->state = AST_STATE_RING;
611                                         ast->rings = 1;
612                                         p->f.frametype = AST_FRAME_CONTROL;
613                                         p->f.subclass = AST_CONTROL_OFFHOOK;
614                                         ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
615                                         return &p->f;
616                                 default:
617                                         ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->state);
618                                 }
619                                 break;
620                         case SIG_EM:
621                         case SIG_EMWINK:
622                         case SIG_FEATD:
623                         case SIG_FXSLS:
624                         case SIG_FXSGS:
625                         case SIG_FXSKS:
626                                 if (ast->state == AST_STATE_DOWN) {
627                                         if (option_debug)
628                                                 ast_log(LOG_DEBUG, "Ring detected\n");
629                                         p->f.frametype = AST_FRAME_CONTROL;
630                                         p->f.subclass = AST_CONTROL_RING;
631                                 } else if (ast->state == AST_STATE_RINGING) {
632                                         if (option_debug)
633                                                 ast_log(LOG_DEBUG, "Line answered\n");
634                                         p->f.frametype = AST_FRAME_CONTROL;
635                                         p->f.subclass = AST_CONTROL_ANSWER;
636                                         ast->state = AST_STATE_UP;
637                                 } else 
638                                         ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->state, p->channel);
639                                 break;
640                         default:
641                                 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
642                         }
643                         break;
644                 case TOR_EVENT_RINGEROFF:
645                         ast->rings++;
646                         if ((ast->rings > 1) && (p->cidspill)) {
647                                 ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
648                                 free(p->cidspill);
649                                 p->cidspill = NULL;
650                         }
651                         p->f.frametype = AST_FRAME_CONTROL;
652                         p->f.subclass = AST_CONTROL_RINGING;
653                         break;
654                 case TOR_EVENT_RINGERON:
655                 case TOR_EVENT_NOALARM:
656                         break;
657                 case TOR_EVENT_WINKFLASH:
658                         switch(p->sig) {
659                         case SIG_FXOLS:
660                         case SIG_FXOGS:
661                         case SIG_FXOKS:
662                                 /* XXX For now, treat as a hang up */
663                                 return NULL;
664                         case SIG_EM:
665                         case SIG_EMWINK:
666                         case SIG_FEATD:
667                         case SIG_FXSLS:
668                         case SIG_FXSGS:
669                                 if (p->dialing)
670                                         ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
671                                 else
672                                         ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->state, p->channel);
673                                 break;
674                         default:
675                                 ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
676                         }
677                         break;
678                 case TOR_EVENT_HOOKCOMPLETE:
679                         res = ioctl(zap_fd(p->z), TOR_DIAL, &p->dop);
680                         if (res < 0) {
681                                 ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
682                                 p->dop.dialstr[0] = '\0';
683                                 return NULL;
684                         } else 
685                                 ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
686                         p->dop.dialstr[0] = '\0';
687                         break;
688                 default:
689                         ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
690         }
691         return &p->f;
692  }
693
694 struct ast_frame *tor_exception(struct ast_channel *ast)
695 {
696         return tor_handle_event(ast);
697 }
698
699 struct ast_frame  *tor_read(struct ast_channel *ast)
700 {
701         struct tor_pvt *p = ast->pvt->pvt;
702         int res,x;
703         unsigned char ireadbuf[READ_SIZE];
704         unsigned char *readbuf;
705         
706         p->f.frametype = AST_FRAME_DTMF;
707         p->f.datalen = 0;
708         p->f.timelen = 0;
709         p->f.mallocd = 0;
710         p->f.offset = 0;
711         p->f.src = "tor_read";
712         p->f.data = NULL;
713         
714         /* Check first for any outstanding DTMF characters */
715         if (strlen(p->dtmfq)) {
716                 p->f.subclass = p->dtmfq[0];
717                 memmove(p->dtmfq, p->dtmfq + 1, sizeof(p->dtmfq) - 1);
718                 return &p->f;
719         }
720         
721         if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
722                 /* Read into temporary buffer */
723                 readbuf = ireadbuf;
724         } else if (ast->pvt->rawreadformat == AST_FORMAT_ULAW) {
725                 /* Read ulaw directly into frame */
726                 readbuf = ((unsigned char *)p->buffer) + AST_FRIENDLY_OFFSET;
727         } else {
728                 ast_log(LOG_WARNING, "Don't know how to read frames in format %d\n", ast->pvt->rawreadformat);
729                 return NULL;
730         }
731         CHECK_BLOCKING(ast);
732         res = zap_recchunk(p->z, readbuf, READ_SIZE, ZAP_DTMFINT);
733         ast->blocking = 0;
734         /* Check for hangup */
735         if (res < 0) {
736                 if (res == -1) 
737                         ast_log(LOG_WARNING, "tor_rec: %s\n", strerror(errno));
738                 return NULL;
739         }
740         if (res != READ_SIZE) {
741                 if (option_debug)
742                         ast_log(LOG_DEBUG, "Short read, must be DTMF or something...\n");
743                 /* XXX UGLY!!  Zapata's DTMF handling is a bit ugly XXX */
744                 if (zap_dtmfwaiting(p->z) && !strlen(zap_dtmfbuf(p->z))) {
745                         zap_getdtmf(p->z, 1, NULL, 0, 1, 1, 0);
746                 }
747                 if (strlen(zap_dtmfbuf(p->z))) {
748                         ast_log(LOG_DEBUG, "Got some dtmf ('%s')... on channel %s\n", zap_dtmfbuf(p->z), ast->name);
749                         /* DTMF tone detected.  Queue and erturn */
750                         strncpy(p->dtmfq + strlen(p->dtmfq), zap_dtmfbuf(p->z), sizeof(p->dtmfq) - strlen(p->dtmfq));
751                         zap_clrdtmfn(p->z);
752                 } else {
753                         return tor_handle_event(ast);
754                 }
755                 return &p->f;
756         }
757         if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
758                 for (x=0;x<READ_SIZE;x++) {
759                         p->buffer[x + AST_FRIENDLY_OFFSET/2] = ast_mulaw[readbuf[x]];
760                 }
761                 p->f.datalen = READ_SIZE * 2;
762         } else 
763                 p->f.datalen = READ_SIZE;
764
765         /* Handle CallerID Transmission */
766         if ((ast->rings == 1) && (p->cidspill))
767                 send_callerid(p);
768
769         p->f.frametype = AST_FRAME_VOICE;
770         p->f.subclass = ast->pvt->rawreadformat;
771         p->f.timelen = READ_SIZE/8;
772         p->f.mallocd = 0;
773         p->f.offset = AST_FRIENDLY_OFFSET;
774         p->f.data = p->buffer + AST_FRIENDLY_OFFSET/2;
775 #if 0
776         ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->f.datalen, ast->name);
777 #endif  
778         return &p->f;
779 }
780
781 static int my_tor_write(struct tor_pvt *p, unsigned char *buf, int len)
782 {
783         int sent=0;
784         int size;
785         int res;
786         while(len) {
787                 size = len;
788                 if (size > READ_SIZE)
789                         size = READ_SIZE;
790                 res = write(zap_fd(p->z), buf, size);
791                 if (res != size) {
792                         ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
793                         return sent;
794                 }
795                 len -= size;
796                 buf += size;
797         }
798         return sent;
799 }
800
801 static int tor_write(struct ast_channel *ast, struct ast_frame *frame)
802 {
803         struct tor_pvt *p = ast->pvt->pvt;
804         int x;
805         int res;
806         unsigned char outbuf[4096];
807         short *inbuf;
808         /* Write a frame of (presumably voice) data */
809         if (frame->frametype != AST_FRAME_VOICE) {
810                 ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
811                 return -1;
812         }
813         if ((frame->subclass != AST_FORMAT_SLINEAR) && (frame->subclass != AST_FORMAT_ULAW)) {
814                 ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
815                 return -1;
816         }
817         if (p->dialing) {
818                 ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing...\n");
819                 return 0;
820         }
821         if (p->cidspill) {
822                 ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
823                 return 0;
824         }
825         /* Return if it's not valid data */
826         if (!frame->data || !frame->datalen)
827                 return 0;
828         if (frame->datalen > sizeof(outbuf) * 2) {
829                 ast_log(LOG_WARNING, "Frame too large\n");
830                 return 0;
831         }
832         if (frame->subclass == AST_FORMAT_SLINEAR) {
833                 inbuf = frame->data;
834                 for (x=0;x<frame->datalen/2;x++)
835                         outbuf[x] = ast_lin2mu[inbuf[x]+32768];
836                 res = my_tor_write(p, outbuf, frame->datalen/2);
837         } else {
838                 /* uLaw already */
839                 res = my_tor_write(p, (unsigned char *)frame->data, frame->datalen);
840         }
841         if (res < 0) {
842                 ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
843                 return -1;
844         } else if (res != frame->datalen/2) {
845                 /* Some sort of an event */
846                 return 0;
847         }
848         return 0;
849 }
850
851 static struct ast_channel *tor_new(struct tor_pvt *i, int state, int startpbx)
852 {
853         struct ast_channel *tmp;
854         tmp = ast_channel_alloc();
855         if (tmp) {
856                 snprintf(tmp->name, sizeof(tmp->name), "Tor/%d", i->channel);
857                 tmp->type = type;
858                 tmp->fd = zap_fd(i->z);
859                 tmp->nativeformats = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
860                 /* Start out assuming ulaw since it's smaller :) */
861                 tmp->pvt->rawreadformat = AST_FORMAT_ULAW;
862                 tmp->readformat = AST_FORMAT_ULAW;
863                 tmp->pvt->rawwriteformat = AST_FORMAT_ULAW;
864                 tmp->writeformat = AST_FORMAT_ULAW;
865                 
866                 tmp->state = state;
867                 if (state == AST_STATE_RING)
868                         tmp->rings = 1;
869                 tmp->pvt->pvt = i;
870                 tmp->pvt->send_digit = tor_digit;
871                 tmp->pvt->call = tor_call;
872                 tmp->pvt->hangup = tor_hangup;
873                 tmp->pvt->answer = tor_answer;
874                 tmp->pvt->read = tor_read;
875                 tmp->pvt->write = tor_write;
876                 tmp->pvt->bridge = tor_bridge;
877                 tmp->pvt->exception = tor_exception;
878                 if (strlen(i->language))
879                         strncpy(tmp->language, i->language, sizeof(tmp->language));
880                 i->owner = tmp;
881                 pthread_mutex_lock(&usecnt_lock);
882                 usecnt++;
883                 pthread_mutex_unlock(&usecnt_lock);
884                 ast_update_use_count();
885                 strncpy(tmp->context, i->context, sizeof(tmp->context));
886                 if (startpbx) {
887                         if (ast_pbx_start(tmp)) {
888                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
889                                 ast_hangup(tmp);
890                                 tmp = NULL;
891                         }
892                 }
893         } else
894                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
895         return tmp;
896 }
897
898
899 static int ignore_pat(char *s)
900 {
901         int x;
902         for (x=0;x<dialpats;x++)
903                 if (!strcmp(s, keepdialpat[x]))
904                         return 1;
905         return 0;
906 }
907
908 static int bump_gains(struct tor_pvt *p)
909 {
910         int res;
911         /* Bump receive gain by 9.0db */
912         res = set_actual_gain(zap_fd(p->z), 0, 9, 0);
913         if (res) {
914                 ast_log(LOG_WARNING, "Unable to bump gain\n");
915                 return -1;
916         }
917         return 0;
918 }
919
920 static int restore_gains(struct tor_pvt *p)
921 {
922         int res;
923         /* Bump receive gain by 9.0db */
924         res = set_actual_gain(zap_fd(p->z), 0, 0, 0);
925         if (res) {
926                 ast_log(LOG_WARNING, "Unable to restore gain\n");
927                 return -1;
928         }
929         return 0;
930 }
931
932 static void *ss_thread(void *data)
933 {
934         struct ast_channel *chan = data;
935         struct tor_pvt *p = chan->pvt->pvt;
936         char exten[AST_MAX_EXTENSION];
937         char exten2[AST_MAX_EXTENSION];
938         unsigned char buf[256];
939         char cid[256];
940         struct callerid_state *cs;
941         char *name, *number;
942         int flags;
943         int i;
944         char *s1, *s2;
945         int len = 0;
946         int res;
947         if (option_verbose > 2) 
948                 ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
949         zap_clrdtmf(p->z);
950         switch(p->sig) {
951         case SIG_FEATD:
952         case SIG_EMWINK:
953                 zap_wink(p->z);
954                 /* Fall through */
955         case SIG_EM:
956                 res = tone_zone_play_tone(zap_fd(p->z), -1);
957                 zap_clrdtmf(p->z);
958                 /* Wait for the first digit (up to 1 second). */
959                 res = zap_getdtmf(p->z, 1, NULL, 0, 1000, 1000, ZAP_TIMEOUTOK | ZAP_HOOKEXIT);
960
961                 if (res == 1) {
962                         /* If we got it, get the rest */
963                         res = zap_getdtmf(p->z, 50, NULL, 0, 250, 15000, ZAP_TIMEOUTOK | ZAP_HOOKEXIT);
964                 }
965                 if (res == -1) {
966                         ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
967                         ast_hangup(chan);
968                         return NULL;
969                 } else if (res < 0) {
970                         ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
971                         ast_hangup(chan);
972                         return NULL;
973                 }
974                 strncpy(exten, zap_dtmfbuf(p->z), sizeof(exten));
975                 if (!strlen(exten))
976                         strncpy(exten, "s", sizeof(exten));
977                 if (p->sig == SIG_FEATD) {
978                         if (exten[0] == '*') {
979                                 strncpy(exten2, exten, sizeof(exten2));
980                                 /* Parse out extension and callerid */
981                                 s1 = strtok(exten2 + 1, "*");
982                                 s2 = strtok(NULL, "*");
983                                 if (s2) {
984                                         if (strlen(p->callerid))
985                                                 chan->callerid = strdup(p->callerid);
986                                         else
987                                                 chan->callerid = strdup(s1);
988                                         strncpy(exten, s2, sizeof(exten));
989                                 } else
990                                         strncpy(exten, s1, sizeof(exten));
991                         } else
992                                 ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
993                 }
994                 res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_RINGTONE);
995                 if (res < 0)
996                         ast_log(LOG_WARNING, "Unable to start ringback tone on channel %d\n", p->channel);
997                 if (ast_exists_extension(chan, chan->context, exten, 1)) {
998                         strncpy(chan->exten, exten, sizeof(chan->exten));
999                         zap_clrdtmf(p->z);
1000                         res = ast_pbx_run(chan);
1001                         if (res) 
1002                                 ast_log(LOG_WARNING, "PBX exited non-zero\n");
1003                         res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
1004                         return NULL;
1005                 } else {
1006                         if (option_verbose > 2)
1007                                 ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
1008                         sleep(2);
1009                         res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_INFO);
1010                         if (res < 0)
1011                                 ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
1012                         else
1013                                 sleep(1);
1014                         res = ast_streamfile(chan, "ss-noservice", chan->language);
1015                         if (res >= 0)
1016                                 ast_waitstream(chan, "");
1017                         res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
1018                         ast_hangup(chan);
1019                         return NULL;
1020                 }
1021                 break;
1022         case SIG_FXOLS:
1023         case SIG_FXOGS:
1024         case SIG_FXOKS:
1025                 /* Read the first digit */
1026                 res = zap_getdtmf(p->z, 1, NULL, 0, firstdigittimeout, firstdigittimeout, ZAP_HOOKEXIT | ZAP_TIMEOUTOK);
1027                 if (res < 0) {
1028                         if (option_debug)
1029                                 ast_log(LOG_DEBUG, "getdtmf returned %d (%s)...\n", res, strerror(errno));
1030                         /* Got hung up on apparently.  Stop any playing tones.  We're done */
1031                         res = tone_zone_play_tone(zap_fd(p->z), -1);
1032                         ast_hangup(chan);
1033                         return NULL;
1034                 }
1035                 if (res) {
1036                         strncpy(exten + len, zap_dtmfbuf(p->z), sizeof(exten) - len);
1037                         len++;
1038                         if (ast_exists_extension(chan, chan->context, exten, 1)) {
1039                                 if (!ignore_pat(exten)) {
1040                                         res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_RINGTONE);
1041                                         if (res < 0)
1042                                                 ast_log(LOG_WARNING, "Unable to start ringback tone on channel %d\n", p->channel);
1043                                 }
1044                                 /* Check for a single digit extension */
1045                                 strncpy(chan->exten, exten, sizeof(chan->exten));
1046                                 zap_clrdtmf(p->z);
1047                                 res = ast_pbx_run(chan);
1048                                 if (res) 
1049                                         ast_log(LOG_WARNING, "PBX exited non-zero\n");
1050                                 res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
1051                                 return NULL;
1052                         }
1053                         
1054                         if (!ignore_pat(exten))
1055                                 tone_zone_play_tone(zap_fd(p->z), -1);
1056                         while(len < AST_MAX_EXTENSION-1) {
1057                                 zap_clrdtmf(p->z);
1058                                 res = zap_getdtmf(p->z, 1, NULL, 0, gendigittimeout, gendigittimeout, ZAP_HOOKEXIT | ZAP_TIMEOUTOK);
1059                                 if (res < 0) {
1060                                         ast_log(LOG_DEBUG, "getdtmf returned < 0...\n");
1061                                         res = tone_zone_play_tone(zap_fd(p->z), -1);
1062                                         ast_hangup(chan);
1063                                         return NULL;
1064                                 } else if (res == 0) {
1065                                         ast_log(LOG_DEBUG, "not enough digits...\n");
1066                                         res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
1067                                         tor_wait_event(zap_fd(p->z));
1068                                         ast_hangup(chan);
1069                                         return NULL;
1070                                 } else {
1071                                         strncpy(exten + len, zap_dtmfbuf(p->z), sizeof(exten) - len);
1072                                         len++;
1073                                         if (!ignore_pat(exten))
1074                                                 tone_zone_play_tone(zap_fd(p->z), -1);
1075                                         if (ast_exists_extension(chan, chan->context, exten, 1)) {
1076                                                 res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_RINGTONE);
1077                                                 if (res < 0)
1078                                                         ast_log(LOG_WARNING, "Unable to start ringback tone on channel %d\n", p->channel);
1079                                                 strncpy(chan->exten, exten, sizeof(chan->exten));
1080                                                 if (strlen(p->callerid))
1081                                                         chan->callerid = strdup(p->callerid);
1082                                                 zap_clrdtmf(p->z);
1083                                                 res = ast_pbx_run(chan);
1084                                                 if (res) 
1085                                                         ast_log(LOG_WARNING, "PBX exited non-zero\n");
1086                                                 res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
1087                                                 return NULL;
1088                                         } else if (!ast_canmatch_extension(chan, chan->context, exten, 1)) {
1089                                                 printf("Can't match %s is context %s\n", exten, chan->context);
1090                                                 break;
1091                                         }
1092                                 }
1093                         }
1094                 }
1095                 break;
1096         case SIG_FXSLS:
1097         case SIG_FXSGS:
1098         case SIG_FXSKS:
1099                 if (p->use_callerid) {
1100                         cs = callerid_new();
1101                         if (cs) {
1102 #if 1
1103                                 bump_gains(p);
1104 #endif                          
1105                                 len = 0;
1106                                 for(;;) {       
1107                                         i = TOR_IOMUX_READ | TOR_IOMUX_SIGEVENT;
1108                                         if ((res = ioctl(zap_fd(p->z), TOR_IOMUX, &i))) {
1109                                                 ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1110                                                 callerid_free(cs);
1111                                                 ast_hangup(chan);
1112                                                 return NULL;
1113                                         }
1114                                         if (i & TOR_IOMUX_SIGEVENT) {
1115                                                 res = tor_get_event(zap_fd(p->z));
1116                                                 ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
1117                                                 res = 0;
1118                                                 break;
1119                                         } else if (i & TOR_IOMUX_READ) {
1120                                                 res = read(zap_fd(p->z), buf + len, sizeof(buf) - len);
1121                                                 if (res < 0) {
1122                                                         if (errno != ELAST) {
1123                                                                 ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1124                                                                 callerid_free(cs);
1125                                                                 ast_hangup(chan);
1126                                                                 return NULL;
1127                                                         }
1128                                                         break;
1129                                                 }
1130                                                 res = callerid_feed(cs, buf, res);
1131                                                 if (res < 0) {
1132                                                         ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
1133                                                         break;
1134                                                 } else if (res)
1135                                                         break;
1136                                         }
1137                                 }
1138                                 if (res == 1) {
1139                                         callerid_get(cs, &number, &name, &flags);
1140                                         if (option_debug)
1141                                                 ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
1142                                 }
1143 #if 1
1144                                 restore_gains(p);
1145 #endif                          
1146                                 if (res < 0) {
1147                                         ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
1148                                 }
1149                         } else
1150                                 ast_log(LOG_WARNING, "Unable to get caller ID space\n");
1151                 }
1152                 if (name && number) {
1153                         snprintf(cid, sizeof(cid), "\"%s\" <%s>", name, number);
1154                 } else if (name) {
1155                         snprintf(cid, sizeof(cid), "\"%s\"", name);
1156                 } else if (number) {
1157                         snprintf(cid, sizeof(cid), "%s", number);
1158                 } else {
1159                         strcpy(cid, "");
1160                 }
1161                 if (strlen(cid))
1162                         chan->callerid = strdup(cid);
1163                 chan->state = AST_STATE_RING;
1164                 chan->rings = 1;
1165                 res = ast_pbx_run(chan);
1166                 if (res) {
1167                         ast_hangup(chan);
1168                         ast_log(LOG_WARNING, "PBX exited non-zero\n");
1169                 }
1170                 return NULL;
1171         default:
1172                 ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
1173                 res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
1174                 if (res < 0)
1175                                 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
1176         }
1177         res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
1178         if (res < 0)
1179                         ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
1180         ast_hangup(chan);
1181         return NULL;
1182 }
1183
1184 static int handle_init_event(struct tor_pvt *i, int event)
1185 {
1186         int res;
1187         pthread_t threadid;
1188         struct ast_channel *chan;
1189         /* Handle an event on a given channel for the monitor thread. */
1190         switch(event) {
1191         case TOR_EVENT_RINGOFFHOOK:
1192                 /* Got a ring/answer.  What kind of channel are we? */
1193                 switch(i->sig) {
1194                 case SIG_FXOLS:
1195                 case SIG_FXOGS:
1196                 case SIG_FXOKS:
1197                         if (i->immediate) {
1198                                 /* The channel is immediately up.  Start right away */
1199                                 chan = tor_new(i, AST_STATE_UP, 1);
1200                                 if (!chan)  {
1201                                         ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
1202                                         res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
1203                                         if (res < 0)
1204                                                 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
1205                                 }
1206                         } else {
1207                                 res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_DIALTONE);
1208                                 if (res < 0) 
1209                                         ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
1210                                 /* Check for callerid, digits, etc */
1211                                 chan = tor_new(i, AST_STATE_DOWN, 0);
1212                                 if (pthread_create(&threadid, NULL, ss_thread, chan)) {
1213                                         ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
1214                                         res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
1215                                         if (res < 0)
1216                                                 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
1217                                         ast_hangup(chan);
1218                                 }
1219                         }
1220                         break;
1221                 case SIG_EMWINK:
1222                 case SIG_FEATD:
1223                 case SIG_EM:
1224                 case SIG_FXSLS:
1225                 case SIG_FXSGS:
1226                 case SIG_FXSKS:
1227                                 /* Check for callerid, digits, etc */
1228                                 chan = tor_new(i, AST_STATE_RING, 0);
1229                                 if (pthread_create(&threadid, NULL, ss_thread, chan)) {
1230                                         ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
1231                                         res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
1232                                         if (res < 0)
1233                                                 ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
1234                                         ast_hangup(chan);
1235                                 }
1236                                 break;
1237                 default:
1238                         ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
1239                         res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
1240                         if (res < 0)
1241                                         ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
1242                         return -1;
1243                 }
1244                 break;
1245         case TOR_EVENT_WINKFLASH:
1246         case TOR_EVENT_ONHOOK:
1247                 /* Back on hook.  Hang up. */
1248                 switch(i->sig) {
1249                 case SIG_FXOLS:
1250                 case SIG_FXOGS:
1251                 case SIG_FXOKS:
1252                 case SIG_FEATD:
1253                 case SIG_EM:
1254                 case SIG_EMWINK:
1255                 case SIG_FXSLS:
1256                 case SIG_FXSGS:
1257                 case SIG_FXSKS:
1258                         res = tone_zone_play_tone(zap_fd(i->z), -1);
1259                         tor_set_hook(zap_fd(i->z), TOR_ONHOOK);
1260                         break;
1261                 default:
1262                         ast_log(LOG_WARNING, "Don't know hwo to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
1263                         res = tone_zone_play_tone(zap_fd(i->z), -1);
1264                         return -1;
1265                 }
1266                 break;
1267         }
1268         return 0;
1269 }
1270
1271 static void *do_monitor(void *data)
1272 {
1273         fd_set rfds;
1274         fd_set efds;
1275         int n, res;
1276         struct tor_pvt *i;
1277         /* This thread monitors all the frame relay interfaces which are not yet in use
1278            (and thus do not have a separate thread) indefinitely */
1279         /* From here on out, we die whenever asked */
1280 #if 0
1281         if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
1282                 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
1283                 return NULL;
1284         }
1285         ast_log(LOG_DEBUG, "Monitor starting...\n");
1286 #endif
1287         for(;;) {
1288                 /* Don't let anybody kill us right away.  Nobody should lock the interface list
1289                    and wait for the monitor list, but the other way around is okay. */
1290                 if (pthread_mutex_lock(&monlock)) {
1291                         ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
1292                         return NULL;
1293                 }
1294                 /* Lock the interface list */
1295                 if (pthread_mutex_lock(&iflock)) {
1296                         ast_log(LOG_ERROR, "Unable to grab interface lock\n");
1297                         pthread_mutex_unlock(&monlock);
1298                         return NULL;
1299                 }
1300                 /* Build the stuff we're going to select on, that is the socket of every
1301                    tor_pvt that does not have an associated owner channel */
1302                 n = -1;
1303                 FD_ZERO(&efds);
1304                 i = iflist;
1305                 while(i) {
1306                         if (FD_ISSET(zap_fd(i->z), &efds)) 
1307                                 ast_log(LOG_WARNING, "Descriptor %d appears twice?\n", zap_fd(i->z));
1308                         if (!i->owner) {
1309                                 /* This needs to be watched, as it lacks an owner */
1310                                 FD_SET(zap_fd(i->z), &efds);
1311                                 if (zap_fd(i->z) > n)
1312                                         n = zap_fd(i->z);
1313                         }
1314                         i = i->next;
1315                 }
1316                 /* Okay, now that we know what to do, release the interface lock */
1317                 pthread_mutex_unlock(&iflock);
1318                 
1319                 /* And from now on, we're okay to be killed, so release the monitor lock as well */
1320                 pthread_mutex_unlock(&monlock);
1321                 pthread_testcancel();
1322                 /* Wait indefinitely for something to happen */
1323                 res = select(n + 1, &rfds, NULL, &efds, NULL);
1324                 pthread_testcancel();
1325                 /* Okay, select has finished.  Let's see what happened.  */
1326                 if (res < 0) {
1327                         if ((errno != EAGAIN) && (errno != EINTR))
1328                                 ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
1329                         continue;
1330                 }
1331                 /* Alright, lock the interface list again, and let's look and see what has
1332                    happened */
1333                 if (pthread_mutex_lock(&iflock)) {
1334                         ast_log(LOG_WARNING, "Unable to lock the interface list\n");
1335                         continue;
1336                 }
1337                 i = iflist;
1338                 while(i) {
1339                         if (FD_ISSET(zap_fd(i->z), &efds)) {
1340                                 if (i->owner) {
1341                                         ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", zap_fd(i->z));
1342                                         i = i->next;
1343                                         continue;
1344                                 }
1345                                 res = tor_get_event(zap_fd(i->z));
1346                                 ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
1347                                 handle_init_event(i, res);
1348                         }
1349                         i=i->next;
1350                 }
1351                 pthread_mutex_unlock(&iflock);
1352         }
1353         /* Never reached */
1354         return NULL;
1355         
1356 }
1357
1358 static int restart_monitor(void)
1359 {
1360         /* If we're supposed to be stopped -- stay stopped */
1361         if (monitor_thread == -2)
1362                 return 0;
1363         if (pthread_mutex_lock(&monlock)) {
1364                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
1365                 return -1;
1366         }
1367         if (monitor_thread == pthread_self()) {
1368                 pthread_mutex_unlock(&monlock);
1369                 ast_log(LOG_WARNING, "Cannot kill myself\n");
1370                 return -1;
1371         }
1372         if (monitor_thread) {
1373 #if 1
1374                 pthread_cancel(monitor_thread);
1375 #endif
1376                 pthread_kill(monitor_thread, SIGURG);
1377 #if 0
1378                 pthread_join(monitor_thread, NULL);
1379 #endif
1380         }
1381         /* Start a new monitor */
1382         if (pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
1383                 pthread_mutex_unlock(&monlock);
1384                 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
1385                 return -1;
1386         }
1387         pthread_mutex_unlock(&monlock);
1388         return 0;
1389 }
1390
1391 static struct tor_pvt *mkif(int channel, int signalling)
1392 {
1393         /* Make a tor_pvt structure for this interface */
1394         struct tor_pvt *tmp;
1395         char fn[80];
1396 #if 1
1397         struct tor_bufferinfo bi;
1398 #endif  
1399         int res;
1400         TOR_PARAMS p;
1401
1402         tmp = malloc(sizeof(struct tor_pvt));
1403         if (tmp) {
1404                 memset(tmp, 0, sizeof(struct tor_pvt));
1405                 snprintf(fn, sizeof(fn), "/dev/tor/%d", channel);
1406                 /* Open non-blocking */
1407                 tmp->z = zap_open(fn, 1);
1408                 /* Allocate a zapata structure */
1409                 if (!tmp->z) {
1410                         ast_log(LOG_ERROR, "Unable to open channel %d: %s\n", channel, strerror(errno));
1411                         free(tmp);
1412                         return NULL;
1413                 }
1414                 res = ioctl(zap_fd(tmp->z), TOR_GET_PARAMS, &p);
1415                 if (res < 0) {
1416                         ast_log(LOG_ERROR, "Unable to get parameters\n");
1417                         free(tmp);
1418                         return NULL;
1419                 }
1420                 if (p.sigtype != (signalling & 0xf)) {
1421                         ast_log(LOG_ERROR, "Signalling requested is %s but line is in %s signalling\n", sig2str(signalling), sig2str(p.sigtype));
1422                         return NULL;
1423                 }
1424                 /* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
1425                 if ((signalling == SIG_FXSKS) || (signalling == SIG_FXSLS)) {
1426                         p.starttime = 250;
1427                         res = ioctl(zap_fd(tmp->z), TOR_SET_PARAMS, &p);
1428                         if (res < 0) {
1429                                 ast_log(LOG_ERROR, "Unable to set parameters\n");
1430                                 free(tmp);
1431                                 return NULL;
1432                         }
1433                 }
1434 #if 0
1435                 res = fcntl(zap_fd(tmp->z), F_GETFL);
1436                 if (res >= 0) {
1437                         res |= O_NONBLOCK;
1438                         if (fcntl(zap_fd(tmp->z), F_SETFL, res))
1439                                 ast_log(LOG_WARNING, "Unable to set non-blocking mode on channel %d\n", channel);
1440                 } else
1441                         ast_log(LOG_WARNING, "Unable to read flags on channel %d\n", channel);
1442 #endif                  
1443 #if 1
1444                 res = ioctl(zap_fd(tmp->z), TOR_GET_BUFINFO, &bi);
1445                 if (!res) {
1446                         bi.txbufpolicy = POLICY_IMMEDIATE;
1447                         bi.rxbufpolicy = POLICY_IMMEDIATE;
1448                         bi.numbufs = 4;
1449                         res = ioctl(zap_fd(tmp->z), TOR_SET_BUFINFO, &bi);
1450                         if (res < 0) {
1451                                 ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
1452                         }
1453                 } else
1454                         ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
1455 #endif
1456                 tmp->immediate = immediate;
1457                 tmp->state = tor_STATE_DOWN;
1458                 tmp->sig = signalling;
1459                 tmp->use_callerid = use_callerid;
1460                 tmp->channel = channel;
1461                 tmp->stripmsd = stripmsd;
1462                 strncpy(tmp->language, language, sizeof(tmp->language));
1463                 strncpy(tmp->context, context, sizeof(tmp->context));
1464                 strncpy(tmp->callerid, callerid, sizeof(tmp->callerid));
1465                 tmp->group = cur_group;
1466                 tmp->next = NULL;
1467                 tmp->ringgothangup = 0;
1468                 /* Hang it up to be sure it's good */
1469                 tor_set_hook(zap_fd(tmp->z), TOR_ONHOOK);
1470                 
1471         }
1472         return tmp;
1473 }
1474
1475 static struct ast_channel *tor_request(char *type, int format, void *data)
1476 {
1477         int oldformat;
1478         int groupmatch = 0;
1479         int channelmatch = -1;
1480         struct tor_pvt *p;
1481         struct ast_channel *tmp = NULL;
1482         char *dest=NULL;
1483         int x;
1484         char *s;
1485         
1486         /* We do signed linear */
1487         oldformat = format;
1488         format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
1489         if (!format) {
1490                 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
1491                 return NULL;
1492         }
1493         if (data) {
1494                 dest = strdup((char *)data);
1495         } else {
1496                 ast_log(LOG_WARNING, "Channel requested with no data\n");
1497                 return NULL;
1498         }
1499         if (dest[0] == 'g') {
1500                 /* Retrieve the group number */
1501                 s = strtok(dest  + 1, "/");
1502                 if (sscanf(s, "%d", &x) != 1) {
1503                         ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
1504                         free(dest);
1505                         return NULL;
1506                 }
1507                 groupmatch = 1 << x;
1508         } else {
1509                 s = strtok(dest, "/");
1510                 if (sscanf(s, "%d", &x) != 1) {
1511                         ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
1512                         free(dest);
1513                         return NULL;
1514                 }
1515                 channelmatch = x;
1516         }
1517         /* Search for an unowned channel */
1518         if (pthread_mutex_lock(&iflock)) {
1519                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
1520                 return NULL;
1521         }
1522         p = iflist;
1523         while(p && !tmp) {
1524                 if (!p->owner &&        /* No current owner */
1525                     ((channelmatch < 0) || (p->channel == channelmatch)) && /* Right channel */
1526                         (((p->group & groupmatch) == groupmatch))                               /* Right group */
1527                 ) {
1528                         if (option_debug)
1529                                 ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
1530                         tmp = tor_new(p, AST_STATE_RESERVED, 0);
1531                         break;
1532                 }
1533                 p = p->next;
1534         }
1535         pthread_mutex_unlock(&iflock);
1536         restart_monitor();
1537         return tmp;
1538 }
1539
1540
1541 static int get_group(char *s)
1542 {
1543         char *copy;
1544         char *piece;
1545         int start, finish,x;
1546         int group = 0;
1547         copy = strdup(s);
1548         if (!copy) {
1549                 ast_log(LOG_ERROR, "Out of memory\n");
1550                 return 0;
1551         }
1552         piece = strtok(copy, ",");
1553         while(piece) {
1554                 if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
1555                         /* Range */
1556                 } else if (sscanf(piece, "%d", &start)) {
1557                         /* Just one */
1558                         finish = start;
1559                 } else {
1560                         ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.  Using '0'\n", s,piece);
1561                         return 0;
1562                 }
1563                 piece = strtok(NULL, ",");
1564                 for (x=start;x<=finish;x++) {
1565                         if ((x > 31) || (x < 0)) {
1566                                 ast_log(LOG_WARNING, "Ignoring invalid group %d\n", x);
1567                         } else
1568                                 group |= (1 << x);
1569                 }
1570         }
1571         free(copy);
1572         return group;
1573 }
1574
1575 int load_module()
1576 {
1577         struct ast_config *cfg;
1578         struct ast_variable *v;
1579         struct tor_pvt *tmp;
1580         char *chan;
1581         int start, finish,x;
1582         cfg = ast_load(config);
1583
1584         /* We *must* have a config file otherwise stop immediately */
1585         if (!cfg) {
1586                 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
1587                 return -1;
1588         }
1589         
1590
1591         if (pthread_mutex_lock(&iflock)) {
1592                 /* It's a little silly to lock it, but we mind as well just to be sure */
1593                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
1594                 return -1;
1595         }
1596         v = ast_variable_browse(cfg, "channels");
1597         while(v) {
1598                 /* Create the interface list */
1599                 if (!strcasecmp(v->name, "channel")) {
1600                         if (cur_signalling < 0) {
1601                                 ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
1602                                 ast_destroy(cfg);
1603                                 pthread_mutex_unlock(&iflock);
1604                                 unload_module();
1605                                 return -1;
1606                         }
1607                         chan = strtok(v->value, ",");
1608                         while(chan) {
1609                                 if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
1610                                         /* Range */
1611                                 } else if (sscanf(chan, "%d", &start)) {
1612                                         /* Just one */
1613                                         finish = start;
1614                                 } else {
1615                                         ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", v->value, chan);
1616                                         ast_destroy(cfg);
1617                                         pthread_mutex_unlock(&iflock);
1618                                         unload_module();
1619                                         return -1;
1620                                 }
1621                                 if (finish < start) {
1622                                         ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
1623                                         x = finish;
1624                                         finish = start;
1625                                         start = x;
1626                                 }
1627                                 for (x=start;x<=finish;x++) {
1628                                         tmp = mkif(x, cur_signalling);
1629                                         if (tmp) {
1630                                                 tmp->next = iflist;
1631                                                 iflist = tmp;
1632                                                 if (option_verbose > 2)
1633                                                         ast_verbose(VERBOSE_PREFIX_3 "Registered channel %d, %s signalling\n", x, sig2str(tmp->sig));
1634                                         } else {
1635                                                 ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
1636                                                 ast_destroy(cfg);
1637                                                 pthread_mutex_unlock(&iflock);
1638                                                 unload_module();
1639                                                 return -1;
1640                                         }
1641                                 }
1642                                 chan = strtok(NULL, ",");
1643                         }
1644                 } else if (!strcasecmp(v->name, "context")) {
1645                         strncpy(context, v->value, sizeof(context));
1646                 } else if (!strcasecmp(v->name, "language")) {
1647                         strncpy(language, v->value, sizeof(language));
1648                 } else if (!strcasecmp(v->name, "stripmsd")) {
1649                         stripmsd = atoi(v->value);
1650                 } else if (!strcasecmp(v->name, "group")) {
1651                         cur_group = get_group(v->value);
1652                 } else if (!strcasecmp(v->name, "immediate")) {
1653                         immediate = ast_true(v->value);
1654                 } else if (!strcasecmp(v->name, "callerid")) {
1655                         if (!strcasecmp(v->value, "asreceived"))
1656                                 strcpy(callerid,"");
1657                         else
1658                                 strncpy(callerid, v->value, sizeof(callerid));
1659                 } else if (!strcasecmp(v->name, "ignorepat")) {
1660                         if (dialpats < AST_MAX_DIAL_PAT - 1) {
1661                                 strncpy(keepdialpat[dialpats], v->value, sizeof(keepdialpat[dialpats]));
1662                                 dialpats++;
1663                         } else
1664                                 ast_log(LOG_WARNING, "Too many dial patterns, ignoring '%s'\n", v->value);
1665                 } else if (!strcasecmp(v->name, "signalling")) {
1666                         if (!strcasecmp(v->value, "em")) {
1667                                 cur_signalling = SIG_EM;
1668                         } else if (!strcasecmp(v->value, "em_w")) {
1669                                 cur_signalling = SIG_EMWINK;
1670                         } else if (!strcasecmp(v->value, "fxs_ls")) {
1671                                 cur_signalling = SIG_FXSLS;
1672                         } else if (!strcasecmp(v->value, "fxs_gs")) {
1673                                 cur_signalling = SIG_FXSGS;
1674                         } else if (!strcasecmp(v->value, "fxs_ks")) {
1675                                 cur_signalling = SIG_FXSKS;
1676                         } else if (!strcasecmp(v->value, "fxo_ls")) {
1677                                 cur_signalling = SIG_FXOLS;
1678                         } else if (!strcasecmp(v->value, "fxo_gs")) {
1679                                 cur_signalling = SIG_FXOGS;
1680                         } else if (!strcasecmp(v->value, "fxo_ks")) {
1681                                 cur_signalling = SIG_FXOKS;
1682                         } else if (!strcasecmp(v->value, "featd")) {
1683                                 cur_signalling = SIG_FEATD;
1684                         } else {
1685                                 ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
1686                                 ast_destroy(cfg);
1687                                 pthread_mutex_unlock(&iflock);
1688                                 unload_module();
1689                                 return -1;
1690                         }
1691                 } else
1692                         ast_log(LOG_DEBUG, "Ignoring %s\n", v->name);
1693                 v = v->next;
1694         }
1695         pthread_mutex_unlock(&iflock);
1696         /* Make sure we can register our Tor channel type */
1697         if (ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR |  AST_FORMAT_ULAW, tor_request)) {
1698                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
1699                 ast_destroy(cfg);
1700                 unload_module();
1701                 return -1;
1702         }
1703         ast_destroy(cfg);
1704         /* And start the monitor for the first time */
1705         restart_monitor();
1706         return 0;
1707 }
1708
1709 int unload_module()
1710 {
1711         struct tor_pvt *p, *pl;
1712         /* First, take us out of the channel loop */
1713         ast_channel_unregister(type);
1714         if (!pthread_mutex_lock(&iflock)) {
1715                 /* Hangup all interfaces if they have an owner */
1716                 p = iflist;
1717                 while(p) {
1718                         if (p->owner)
1719                                 ast_softhangup(p->owner);
1720                         p = p->next;
1721                 }
1722                 iflist = NULL;
1723                 pthread_mutex_unlock(&iflock);
1724         } else {
1725                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1726                 return -1;
1727         }
1728         if (!pthread_mutex_lock(&monlock)) {
1729                 if (monitor_thread) {
1730                         pthread_cancel(monitor_thread);
1731                         pthread_kill(monitor_thread, SIGURG);
1732                         pthread_join(monitor_thread, NULL);
1733                 }
1734                 monitor_thread = -2;
1735                 pthread_mutex_unlock(&monlock);
1736         } else {
1737                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1738                 return -1;
1739         }
1740
1741         if (!pthread_mutex_lock(&iflock)) {
1742                 /* Destroy all the interfaces and free their memory */
1743                 p = iflist;
1744                 while(p) {
1745                         /* Free any callerid */
1746                         if (p->cidspill)
1747                                 free(p->cidspill);
1748                         /* Close the zapata thingy */
1749                         if (p->z)
1750                                 zap_close(p->z);
1751                         pl = p;
1752                         p = p->next;
1753                         /* Free associated memory */
1754                         free(pl);
1755                 }
1756                 iflist = NULL;
1757                 pthread_mutex_unlock(&iflock);
1758         } else {
1759                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
1760                 return -1;
1761         }
1762                 
1763         return 0;
1764 }
1765 int usecount()
1766 {
1767         int res;
1768         pthread_mutex_lock(&usecnt_lock);
1769         res = usecnt;
1770         pthread_mutex_unlock(&usecnt_lock);
1771         return res;
1772 }
1773
1774 char *description()
1775 {
1776         return desc;
1777 }
1778
1779 char *key()
1780 {
1781         return ASTERISK_GPL_KEY;
1782 }