another round of version tag updates, along with 'show version files' pattern filtering
[asterisk/asterisk.git] / channels / chan_modem.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * A/Open ITU-56/2 Voice Modem Driver (Rockwell, IS-101, and others)
5  * 
6  * Copyright (C) 1999 - 2005, Digium, Inc.
7  *
8  * Mark Spencer <markster@digium.com>
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 <string.h>
16 #include <sys/socket.h>
17 #include <sys/time.h>
18 #include <errno.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <fcntl.h>
24 #include <sys/ioctl.h>
25 #include <sys/termios.h>
26 #include <sys/signal.h>
27 #include <ctype.h>
28
29 #include "asterisk.h"
30
31 ASTERISK_FILE_VERSION("$Revision$")
32
33 #include "asterisk/lock.h"
34 #include "asterisk/channel.h"
35 #include "asterisk/config.h"
36 #include "asterisk/logger.h"
37 #include "asterisk/module.h"
38 #include "asterisk/pbx.h"
39 #include "asterisk/options.h"
40 #include "asterisk/vmodem.h"
41 #include "asterisk/utils.h"
42
43 /* Up to 10 seconds for an echo to arrive */
44 #define ECHO_TIMEOUT 10
45
46 static const char desc[] = "Generic Voice Modem Driver";
47 static const char tdesc[] = "Generic Voice Modem Channel Driver";
48 static const char type[] = "Modem";
49 static const char config[] = "modem.conf";
50 static char dialtype = 'T';
51 static int gmode = MODEM_MODE_IMMEDIATE;
52
53 /* Default modem type */
54 static char mtype[80] = "autodetect";
55 /* Default context for incoming calls */
56 static char context[AST_MAX_EXTENSION]= "default";
57
58 /* Default language */
59 static char language[MAX_LANGUAGE] = "";
60
61 /* Initialization String */
62 static char initstr[AST_MAX_INIT_STR] = "ATE0Q0";
63
64 /* Default MSN */
65 static char msn[AST_MAX_EXTENSION]="";
66
67 /* Default Listen */
68 static char incomingmsn[AST_MAX_EXTENSION]="";
69
70 /* Default DTMF-detection mode (i4l/asterisk) */
71 static int dtmfmode = MODEM_DTMF_AST;
72 /* Default DTMF-generation mode (i4l (outband) / asterisk (inband) */
73 static int dtmfmodegen = MODEM_DTMF_AST;
74
75 struct ast_dsp *dsp = NULL;
76
77 /* Default valid outgoing MSN */
78 static char outgoingmsn[AST_MAX_EXTENSION]="";
79
80 /* Default group */
81 static ast_group_t cur_group = 0;
82
83 static int usecnt =0;
84
85 static int baudrate = 115200;
86
87 static int stripmsd = 0;
88
89 AST_MUTEX_DEFINE_STATIC(usecnt_lock);
90
91 /* Protect the interface list (of ast_modem_pvt's) */
92 AST_MUTEX_DEFINE_STATIC(iflock);
93
94 /* Protect the monitoring thread, so only one process can kill or start it, and not
95    when it's doing something critical. */
96 AST_MUTEX_DEFINE_STATIC(monlock);
97
98 /* This is the thread for the monitor which checks for input on the channels
99    which are not currently in use.  */
100 static pthread_t monitor_thread = AST_PTHREADT_NULL;
101
102 static int restart_monitor(void);
103
104 static struct ast_channel *modem_request(const char *type, int format, void *data, int *cause);
105 static int modem_digit(struct ast_channel *ast, char digit);
106 static int modem_call(struct ast_channel *ast, char *idest, int timeout);
107 static int modem_hangup(struct ast_channel *ast);
108 static int modem_answer(struct ast_channel *ast);
109 static struct ast_frame *modem_read(struct ast_channel *);
110 static int modem_write(struct ast_channel *ast, struct ast_frame *frame);
111 static int modem_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
112
113 static const struct ast_channel_tech modem_tech = {
114         .type = type,
115         .description = tdesc,
116         .capabilities = AST_FORMAT_SLINEAR,
117         .requester = modem_request,
118         .send_digit = modem_digit,
119         .call = modem_call,
120         .hangup = modem_hangup,
121         .answer = modem_answer,
122         .read = modem_read,
123         .write = modem_write,
124         .fixup = modem_fixup,
125 };
126
127 /* The private structures of the Phone Jack channels are linked for
128    selecting outgoing channels */
129    
130 static struct ast_modem_pvt  *iflist = NULL;
131
132 static int modem_digit(struct ast_channel *ast, char digit)
133 {
134         struct ast_modem_pvt *p;
135         p = ast->tech_pvt;
136         if (p->mc->dialdigit)
137                 return p->mc->dialdigit(p, digit);
138         ast_log(LOG_DEBUG, "Channel %s lacks digit dialing\n", ast->name);
139         return -1;
140 }
141
142 static struct ast_modem_driver *drivers = NULL;
143
144 static struct ast_modem_driver *find_capability(char *ident)
145 {
146         struct ast_modem_driver *mc;
147         int x;
148         mc = drivers;
149         while(mc) {
150                 for (x=0;mc->idents[x];x++) {
151                         if (!strcmp(ident, mc->idents[x])) 
152                                 break;
153                 }
154                 if (mc->idents[x])
155                         break;
156                 mc = mc->next;
157         }
158         if (mc) {
159                 if (mc->incusecnt)
160                         mc->incusecnt();
161         }
162         return mc;
163 }
164
165 static struct ast_modem_driver *find_driver(char *drv)
166 {
167         struct ast_modem_driver *mc;
168         mc = drivers;
169         while(mc) {
170                 if (!strcasecmp(mc->name, drv)) 
171                         break;
172                 mc = mc->next;
173         }
174         if (mc) {
175                 if (mc->incusecnt)
176                         mc->incusecnt();
177         }
178         return mc;
179 }
180
181 int ast_register_modem_driver(struct ast_modem_driver *mc)
182 {
183         mc->next = drivers;
184         drivers = mc;
185         return 0;
186 }
187
188 int ast_unregister_modem_driver(struct ast_modem_driver *mc)
189 {
190         struct ast_modem_driver *last = NULL, *cur;
191         cur = drivers;
192         while(cur) {
193                 if (cur == mc) {
194                         if (last)
195                                 last->next = mc->next;
196                         else
197                                 drivers = mc->next;
198                         return 0;
199                 }
200                 cur = cur->next;
201         }
202         return -1;
203 }
204
205 static int modem_call(struct ast_channel *ast, char *idest, int timeout)
206 {
207         struct ast_modem_pvt *p;
208         int ms = timeout;
209         char rdest[80], *where, dstr[100] = "";
210         char *stringp=NULL;
211         strncpy(rdest, idest, sizeof(rdest)-1);
212         stringp=rdest;
213         strsep(&stringp, ":");
214         where = strsep(&stringp, ":");
215         if (!where) {
216                 ast_log(LOG_WARNING, "Destination %s requres a real destination (device:destination)\n", idest);
217                 return -1;
218         }
219         p = ast->tech_pvt;
220         strncpy(dstr, where + p->stripmsd, sizeof(dstr) - 1);
221         /* if not a transfer or just sending tones, must be in correct state */
222         if (strcasecmp(rdest, "transfer") && strcasecmp(rdest,"sendtones")) {
223                 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
224                         ast_log(LOG_WARNING, "modem_call called on %s, neither down nor reserved\n", ast->name);
225                         return -1;
226                 }
227         } 
228         if (!strcasecmp(rdest,"transfer")) /* if a transfer, put in transfer stuff */
229         {
230                 snprintf(dstr, sizeof(dstr), "!,%s", where + p->stripmsd);
231         }
232         if (!strcasecmp(where, "handset")) {
233                 if (p->mc->setdev)
234                         if (p->mc->setdev(p, MODEM_DEV_HANDSET))
235                                 return -1;
236                 /* Should be immediately up */
237                 ast_setstate(ast, AST_STATE_UP);
238         } else {
239                 if (p->mc->setdev)
240                         if (p->mc->setdev(p, MODEM_DEV_TELCO_SPK))
241                                 return -1;
242                 if (p->mc->dial)
243                         p->mc->dial(p, dstr);
244                 ast_setstate(ast, AST_STATE_DIALING);
245                 while((ast->_state != AST_STATE_UP) && (ms > 0)) {
246                         ms = ast_waitfor(ast, ms);
247                         /* Just read packets and watch what happens */
248                         if (ms > 0) {
249                                 if (!modem_read(ast))
250                                         return -1;
251                         }
252                 }
253                 if (ms < 0)     
254                         return -1;
255         }
256         return 0;
257 }
258
259 int ast_modem_send(struct ast_modem_pvt *p, char *cmd, int len)
260 {
261         int i;
262         usleep(5000);
263         if (!len) {
264                 for(i = 0; cmd[i];)
265                    {
266                         if (fwrite(cmd + i,1,1,p->f) != 1)
267                            {
268                                 if (errno == EWOULDBLOCK) continue;
269                                 return -1;
270                            }
271                         i++;
272                    }
273                 tcdrain(fileno(p->f)); 
274                 fprintf(p->f,"\r\n");
275                 return 0;
276         } else {
277                 if (fwrite(cmd, 1, len, p->f) < len)
278                         return -1;
279                 return 0;
280         }
281 }
282
283 int ast_modem_read_response(struct ast_modem_pvt *p, int timeout)
284 {
285         int res = -1,c,i;
286         timeout *= 1000;
287         p->response[0] = 0;
288         c = i = 0;
289         do {
290                 res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
291                 if (res < 0) {
292                         strncpy(p->response, "(No Response)", sizeof(p->response)-1);
293                         return -1;
294                 }
295                   /* get no more then buffer length */
296                 while(i < sizeof(p->response) - 1)
297                 {
298                         c = fgetc(p->f);  /* get a char */
299                         if (c < 1) /* if error */
300                         {
301                                   /* if nothing in buffer, go back into timeout stuff */
302                                 if (errno == EWOULDBLOCK) break;
303                                 /* return as error */
304                                 strncpy(p->response, "(No Response)", sizeof(p->response)-1);
305                                 return -1;
306                         }
307                           /* save char */
308                         p->response[i++] = c;
309                         p->response[i] = 0;                     
310                           /* if end of input */
311                         if (c == '\n') break;
312                 }
313                 if (c >= 0)  /* if input terminated normally */
314                 {
315                           /* ignore just CR/LF */
316                         if (!strcmp(p->response,"\r\n"))
317                         {
318                                   /* reset input buffer stuff */
319                                 i = 0; 
320                                 p->response[0] = 0;
321                         }
322                         else /* otherwise return with info in buffer */
323                         {
324                                 return 0;
325                         }
326                 }
327         } while(timeout > 0);
328         strncpy(p->response, "(No Response)", sizeof(p->response)-1);
329         return -1;
330 }
331
332 int ast_modem_expect(struct ast_modem_pvt *p, char *result, int timeout)
333 {
334         int res = -1;
335         timeout *= 1000;
336         strncpy(p->response, "(No Response)", sizeof(p->response)-1);
337         do {
338                 res = ast_waitfor_n_fd(&p->fd, 1, &timeout, NULL);
339                 if (res < 0) {
340                         return -1;
341                 }
342                 /* Read a response */
343                 fgets(p->response, sizeof(p->response), p->f);
344 #if     0
345                 fprintf(stderr, "Modem said: %s", p->response);
346 #endif
347                 if (!strncasecmp(p->response, result, strlen(result))) 
348                         return 0;
349         } while(timeout > 0);
350         return -1;
351 }
352
353 void ast_modem_trim(char *s)
354 {
355         int x;
356         x = strlen(s) - 1;
357         while(x >= 0) {
358                 if ((s[x] != '\r') && (s[x] != '\n') && (s[x] != ' '))
359                         break;
360                 s[x] = '\0';
361                 x--;
362         }
363 }
364
365 static int modem_setup(struct ast_modem_pvt *p, int baudrate)
366 {
367
368         /* Make sure there's a modem there and that it's in a reasonable 
369            mode.  Set the baud rate, etc.  */
370         char identity[256];
371         char *ident = NULL;
372         char etx[2] = { 0x10, '!' }; 
373         if (option_debug)
374                 ast_log(LOG_DEBUG, "Setting up modem %s\n", p->dev);
375         if (ast_modem_send(p, etx, 2)) {
376                 ast_log(LOG_WARNING, "Failed to send ETX?\n");
377                 return -1;
378         }
379         if (ast_modem_send(p, "\r\n", 2)) {
380                 ast_log(LOG_WARNING, "Failed to send enter?\n");
381                 return -1;
382         }
383         usleep(10000);
384         /* Read any outstanding stuff */
385         while(!ast_modem_read_response(p, 0));
386         if (ast_modem_send(p, "ATZ", 0)) {
387                 ast_log(LOG_WARNING, "Modem not responding on %s\n", p->dev);
388                 return -1;
389         }
390         if (ast_modem_expect(p, "OK", ECHO_TIMEOUT)) {
391                 ast_log(LOG_WARNING, "Modem reset failed: %s\n", p->response);
392                 return -1;
393         }
394         if (ast_modem_send(p, p->initstr, 0)) {
395                 ast_log(LOG_WARNING, "Modem not responding on %s\n", p->dev);
396                 return -1;
397         }
398         if (ast_modem_expect(p, "OK", ECHO_TIMEOUT)) {
399                 ast_log(LOG_WARNING, "Modem initialization failed: %s\n", p->response);
400                 return -1;
401         }
402         if (ast_modem_send(p, "ATI3", 0)) {
403                 ast_log(LOG_WARNING, "Modem not responding on %s\n", p->dev);
404                 return -1;
405         }
406         if (ast_modem_read_response(p, ECHO_TIMEOUT)) {
407                 ast_log(LOG_WARNING, "Modem did not provide identification\n");
408                 return -1;
409         }
410         strncpy(identity, p->response, sizeof(identity)-1);
411         ast_modem_trim(identity);
412         if (ast_modem_expect(p, "OK", ECHO_TIMEOUT)) {
413                 ast_log(LOG_WARNING, "Modem did not provide identification\n");
414                 return -1;
415         }
416         if (!strcasecmp(mtype, "autodetect")) {
417                 p->mc = find_capability(identity);
418                 if (!p->mc) {
419                         ast_log(LOG_WARNING, "Unable to autodetect modem.  You'll need to specify a driver in modem.conf.  Please report modem identification (%s) and which driver works to markster@linux-support.net.\n", identity); 
420                         return -1;
421                 }
422         } else {
423                 p->mc = find_driver(mtype);
424                 if (!p->mc) {
425                         ast_log(LOG_WARNING, "No driver for modem type '%s'\n", mtype);
426                         return -1;
427                 }
428         }
429         if (p->mc->init) {
430                 if (p->mc->init(p)) {
431                         ast_log(LOG_WARNING, "Modem Initialization Failed on '%s', driver %s.\n", p->dev, p->mc->name);
432                         p->mc->decusecnt();
433                         return -1;
434                 }
435         }                       
436         if (option_verbose > 2) {
437                 ast_verbose(VERBOSE_PREFIX_3 "Configured modem %s with driver %s (%s)\n", p->dev, p->mc->name, p->mc->identify ? (ident = p->mc->identify(p)) : "No identification");
438         }
439         if (ident)
440                 free(ident);
441         return 0;
442 }
443
444 static int modem_hangup(struct ast_channel *ast)
445 {
446         struct ast_modem_pvt *p;
447         if (option_debug)
448                 ast_log(LOG_DEBUG, "modem_hangup(%s)\n", ast->name);
449         p = ast->tech_pvt;
450         /* Hang up */
451         if (p->mc->hangup)
452                 p->mc->hangup(p);
453         /* Re-initialize */
454         if (p->mc->init)
455                 p->mc->init(p);
456         ast_setstate(ast, AST_STATE_DOWN);
457         memset(p->cid_num, 0, sizeof(p->cid_num));
458         memset(p->cid_name, 0, sizeof(p->cid_name));
459         memset(p->dnid, 0, sizeof(p->dnid));
460         ((struct ast_modem_pvt *)(ast->tech_pvt))->owner = NULL;
461         ast_mutex_lock(&usecnt_lock);
462         usecnt--;
463         if (usecnt < 0) 
464                 ast_log(LOG_WARNING, "Usecnt < 0???\n");
465         ast_mutex_unlock(&usecnt_lock);
466         ast_update_use_count();
467         if (option_verbose > 2) 
468                 ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
469         ast->tech_pvt = NULL;
470         ast_setstate(ast, AST_STATE_DOWN);
471         restart_monitor();
472         return 0;
473 }
474
475 static int modem_answer(struct ast_channel *ast)
476 {
477         struct ast_modem_pvt *p;
478         int res=0;
479         if (option_debug)
480                 ast_log(LOG_DEBUG, "modem_answer(%s)\n", ast->name);
481         p = ast->tech_pvt;
482         if (p->mc->answer) {
483                 res = p->mc->answer(p);
484         }
485         if (!res) {
486                 ast->rings = 0;
487                 ast_setstate(ast, AST_STATE_UP);
488         }
489         return res;
490 }
491
492 #if     0
493 static char modem_2digit(char c)
494 {
495         if (c == 12)
496                 return '#';
497         else if (c == 11)
498                 return '*';
499         else if ((c < 10) && (c >= 0))
500                 return '0' + c - 1;
501         else
502                 return '?';
503 }
504 #endif
505 static struct ast_frame *modem_read(struct ast_channel *ast)
506 {
507         struct ast_modem_pvt *p = ast->tech_pvt;
508         struct ast_frame *fr=NULL;
509         if (p->mc->read)
510                 fr = p->mc->read(p);
511         return fr;
512 }
513
514 static int modem_write(struct ast_channel *ast, struct ast_frame *frame)
515 {
516         int res=0;
517         long flags;
518         struct ast_modem_pvt *p = ast->tech_pvt;
519
520         /* Modems tend to get upset when they receive data whilst in
521          * command mode. This makes esp. dial commands short lived.
522          *     Pauline Middelink - 2002-09-24 */
523         if (ast->_state != AST_STATE_UP)
524                 return 0;
525
526         /* Temporarily make non-blocking */
527         flags = fcntl(ast->fds[0], F_GETFL);
528         fcntl(ast->fds[0], F_SETFL, flags | O_NONBLOCK);
529
530         if (p->mc->write)
531                 res = p->mc->write(p, frame);
532
533         /* Block again */
534         fcntl(ast->fds[0], F_SETFL, flags);
535         return res;
536 }
537
538 static int modem_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
539 {
540         struct ast_modem_pvt *p = newchan->tech_pvt;
541 ast_log(LOG_WARNING, "fixup called\n");
542         if (p->owner!=oldchan) {
543             ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n",oldchan,p->owner);
544             return -1;
545         }
546         p->owner = newchan;
547         return 0; 
548 }
549
550 struct ast_channel *ast_modem_new(struct ast_modem_pvt *i, int state)
551 {
552         struct ast_channel *tmp;
553         tmp = ast_channel_alloc(1);
554         if (tmp) {
555                 tmp->tech = &modem_tech;
556                 snprintf(tmp->name, sizeof(tmp->name), "Modem[%s]/%s", i->mc->name, i->dev + 5);
557                 tmp->type = type;
558                 tmp->fds[0] = i->fd;
559                 tmp->nativeformats = i->mc->formats;
560                 ast_setstate(tmp, state);
561                 if (state == AST_STATE_RING)
562                         tmp->rings = 1;
563                 tmp->tech_pvt = i;
564                 strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
565
566                 if (!ast_strlen_zero(i->cid_num))
567                         tmp->cid.cid_num = strdup(i->cid_num);
568                 if (!ast_strlen_zero(i->cid_name))
569                         tmp->cid.cid_name = strdup(i->cid_name);
570
571                 if (strlen(i->language))
572                         strncpy(tmp->language,i->language, sizeof(tmp->language)-1);
573                 if (strlen(i->dnid))
574                         strncpy(tmp->exten, i->dnid, sizeof(tmp->exten) - 1);
575                 i->owner = tmp;
576                 ast_mutex_lock(&usecnt_lock);
577                 usecnt++;
578                 ast_mutex_unlock(&usecnt_lock);
579                 ast_update_use_count();
580                 if (state != AST_STATE_DOWN) {
581                         if (ast_pbx_start(tmp)) {
582                                 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
583                                 ast_hangup(tmp);
584                                 tmp = NULL;
585                         }
586                 }
587         } else
588                 ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
589         return tmp;
590 }
591
592 static void modem_mini_packet(struct ast_modem_pvt *i)
593 {
594         struct ast_frame *fr;
595         fr = i->mc->read(i);
596         if (!fr) return;
597         if (fr->frametype == AST_FRAME_CONTROL) {
598                 if (fr->subclass == AST_CONTROL_RING) {
599                         ast_modem_new(i, AST_STATE_RING);
600                 }
601         }
602 }
603
604 static void *do_monitor(void *data)
605 {
606         fd_set rfds, efds;
607         int n, res;
608         struct ast_modem_pvt *i;
609         /* This thread monitors all the frame relay interfaces which are not yet in use
610            (and thus do not have a separate thread) indefinitely */
611         /* From here on out, we die whenever asked */
612 #if 0
613         if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
614                 ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
615                 return NULL;
616         }
617 #endif
618         for(;;) {
619                 /* Don't let anybody kill us right away.  Nobody should lock the interface list
620                    and wait for the monitor list, but the other way around is okay. */
621                 if (ast_mutex_lock(&monlock)) {
622                         ast_log(LOG_ERROR, "Unable to grab monitor lock\n");
623                         return NULL;
624                 }
625                 /* Lock the interface list */
626                 if (ast_mutex_lock(&iflock)) {
627                         ast_log(LOG_ERROR, "Unable to grab interface lock\n");
628                         ast_mutex_unlock(&monlock);
629                         return NULL;
630                 }
631                 /* Build the stuff we're going to select on, that is the socket of every
632                    ast_modem_pvt that does not have an associated owner channel */
633                 n = -1;
634                 FD_ZERO(&rfds);
635                 FD_ZERO(&efds);
636                 i = iflist;
637                 while(i) {
638                         if (FD_ISSET(i->fd, &rfds)) 
639                                 ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->fd, i->dev);
640                         if (!i->owner) {
641                                 /* This needs to be watched, as it lacks an owner */
642                                 FD_SET(i->fd, &rfds);
643                                 FD_SET(i->fd, &efds);
644                                 if (i->fd > n)
645                                         n = i->fd;
646                         }
647                         
648                         i = i->next;
649                 }
650                 /* Okay, now that we know what to do, release the interface lock */
651                 ast_mutex_unlock(&iflock);
652                 
653                 /* And from now on, we're okay to be killed, so release the monitor lock as well */
654                 ast_mutex_unlock(&monlock);
655 #if 0
656                 ast_log(LOG_DEBUG, "In monitor, n=%d, pid=%d\n", n, getpid());
657 #endif
658                 /* Wait indefinitely for something to happen */
659                 pthread_testcancel();
660                 res = ast_select(n + 1, &rfds, NULL, &efds, NULL);
661                 pthread_testcancel();
662                 /* Okay, select has finished.  Let's see what happened.  */
663                 if (res < 1) {
664                         if ((errno != EINTR) && (errno != EAGAIN))
665                                 ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
666                         continue;
667                 }
668                 /* Alright, lock the interface list again, and let's look and see what has
669                    happened */
670                 if (ast_mutex_lock(&iflock)) {
671                         ast_log(LOG_WARNING, "Unable to lock the interface list\n");
672                         continue;
673                 }
674                 i = iflist;
675                 while(i) {
676                         if (FD_ISSET(i->fd, &rfds) || FD_ISSET(i->fd, &efds)) {
677                                 if (i->owner) {
678                                         ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d, %s)...\n", i->fd, i->dev);
679                                         i = i->next;
680                                         continue;
681                                 }
682                                 modem_mini_packet(i);
683                         }
684                         i=i->next;
685                 }
686                 ast_mutex_unlock(&iflock);
687         }
688         /* Never reached */
689         return NULL;
690         
691 }
692
693 static int restart_monitor()
694 {
695         /* If we're supposed to be stopped -- stay stopped */
696         if (monitor_thread == AST_PTHREADT_STOP)
697                 return 0;
698         if (ast_mutex_lock(&monlock)) {
699                 ast_log(LOG_WARNING, "Unable to lock monitor\n");
700                 return -1;
701         }
702         if (monitor_thread == pthread_self()) {
703                 ast_mutex_unlock(&monlock);
704                 ast_log(LOG_WARNING, "Cannot kill myself\n");
705                 return -1;
706         }
707         if (monitor_thread != AST_PTHREADT_NULL) {
708                 pthread_cancel(monitor_thread);
709                 /* Nudge it a little, as it's probably stuck in select */
710                 pthread_kill(monitor_thread, SIGURG);
711                 pthread_join(monitor_thread, NULL);
712         }
713         /* Start a new monitor */
714         if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) {
715                 ast_mutex_unlock(&monlock);
716                 ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
717                 return -1;
718         }
719         ast_mutex_unlock(&monlock);
720         return 0;
721 }
722
723 static void stty(struct ast_modem_pvt *p)
724 {
725         struct termios mode;
726         memset(&mode, 0, sizeof(mode));
727         if (tcgetattr(p->fd, &mode)) {
728                 ast_log(LOG_WARNING, "Unable to get serial parameters on %s: %s\n", p->dev, strerror(errno));
729                 return;
730         }
731 #ifndef SOLARIS
732         cfmakeraw(&mode);
733 #else
734         mode.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
735                         |INLCR|IGNCR|ICRNL|IXON);
736         mode.c_oflag &= ~OPOST;
737         mode.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
738         mode.c_cflag &= ~(CSIZE|PARENB);
739         mode.c_cflag |= CS8;
740 #endif
741
742         cfsetispeed(&mode, B115200);
743         cfsetospeed(&mode, B115200);
744         if (tcsetattr(p->fd, TCSANOW, &mode)) 
745                 ast_log(LOG_WARNING, "Unable to set serial parameters on %s: %s\n", p->dev, strerror(errno));
746         
747 }
748
749 static struct ast_modem_pvt *mkif(char *iface)
750 {
751         /* Make a ast_modem_pvt structure for this interface */
752         struct ast_modem_pvt *tmp;
753 #if 0
754         int flags;      
755 #endif
756         
757         tmp = malloc(sizeof(struct ast_modem_pvt));
758         if (tmp) {
759                 memset(tmp, 0, sizeof(struct ast_modem_pvt));
760                 tmp->fd = open(iface, O_RDWR | O_NONBLOCK);
761                 if (tmp->fd < 0) {
762                         ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);
763                         free(tmp);
764                         return NULL;
765                 }
766                 strncpy(tmp->language, language, sizeof(tmp->language)-1);
767                 strncpy(tmp->msn, msn, sizeof(tmp->msn)-1);
768                 strncpy(tmp->incomingmsn, incomingmsn, sizeof(tmp->incomingmsn)-1);
769                 tmp->dtmfmode = dtmfmode;
770                 tmp->dtmfmodegen = dtmfmodegen;
771                 snprintf(tmp->outgoingmsn, sizeof(tmp->outgoingmsn), ",%s,", outgoingmsn);
772                 strncpy(tmp->dev, iface, sizeof(tmp->dev)-1);
773                 /* Maybe in the future we want to allow variable
774                    serial settings */
775                 stty(tmp);
776                 tmp->f = fdopen(tmp->fd, "w+");
777                 /* Disable buffering */
778                 setvbuf(tmp->f, NULL, _IONBF,0);
779                 if (tmp->f < 0) {
780                         ast_log(LOG_WARNING, "Unable to fdopen '%s'\n", iface);
781                         free(tmp);
782                         return NULL;
783                 }
784                 tmp->owner = NULL;
785                 tmp->ministate = 0;
786                 tmp->stripmsd = stripmsd;
787                 tmp->dialtype = dialtype;
788                 tmp->mode = gmode;
789                 tmp->group = cur_group;
790                 memset(tmp->cid_num, 0, sizeof(tmp->cid_num));
791                 memset(tmp->cid_name, 0, sizeof(tmp->cid_name));
792                 strncpy(tmp->context, context, sizeof(tmp->context)-1);
793                 strncpy(tmp->initstr, initstr, sizeof(tmp->initstr)-1);
794                 tmp->next = NULL;
795                 tmp->obuflen = 0;
796                 
797                 if (modem_setup(tmp, baudrate) < 0) {
798                         ast_log(LOG_WARNING, "Unable to configure modem '%s'\n", iface);
799                         free(tmp);
800                         return NULL;
801                 }
802         }
803         return tmp;
804 }
805
806 static struct ast_channel *modem_request(const char *type, int format, void *data, int *cause)
807 {
808         int oldformat;
809         struct ast_modem_pvt *p;
810         struct ast_channel *tmp = NULL;
811         char dev[80];
812         ast_group_t group = 0;
813         int groupint;
814         char *stringp=NULL;
815         strncpy(dev, (char *)data, sizeof(dev)-1);
816         stringp=dev;
817         strsep(&stringp, ":");
818         oldformat = format;
819
820         if (dev[0]=='g' && isdigit(dev[1])) {
821                 /* Retrieve the group number */
822                 if (sscanf(dev+1, "%u", &groupint) < 1) {
823                         ast_log(LOG_WARNING, "Unable to determine group from [%s]\n", (char *)data);
824                         return NULL;
825                 }
826                 group = 1 << groupint;
827         }
828
829         /* Search for an unowned channel */
830         if (ast_mutex_lock(&iflock)) {
831                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
832                 return NULL;
833         }
834         p = iflist;
835         while(p) {
836                 if (group) {
837                         /* if it belongs to the proper group, and the format matches
838                          * and it is not in use, we found a candidate! */
839                         if (p->group & group &&
840                             p->mc->formats & format &&
841                             !p->owner) {
842                                 /* XXX Not quite sure that not having an owner is
843                                  * sufficient evidence of beeing a free device XXX */
844                                 tmp = ast_modem_new(p, AST_STATE_DOWN);
845                                 restart_monitor();
846                                 break;
847                         }
848                 } else {
849                         if (!strcmp(dev, p->dev + 5)) {
850                                 if (p->mc->formats & format) {
851                                         if (!p->owner) {
852                                                 tmp = ast_modem_new(p, AST_STATE_DOWN);
853                                                 restart_monitor();
854                                                 break;
855                                         } else
856                                                 ast_log(LOG_WARNING, "Device '%s' is busy\n", p->dev);
857                                 } else 
858                                         ast_log(LOG_WARNING, "Asked for a format %s line on %s\n", ast_getformatname(format), p->dev);
859                                 break;
860                         }
861                 }
862                 p = p->next;
863         }
864         if (!p) 
865                 ast_log(LOG_WARNING, "Requested device '%s' does not exist\n", dev);
866         
867         ast_mutex_unlock(&iflock);
868         return tmp;
869 }
870
871 static ast_group_t get_group(char *s)
872 {
873         char *piece;
874         int start, finish,x;
875         ast_group_t group = 0;
876         char *copy = ast_strdupa(s);
877         char *stringp=NULL;
878         if (!copy) {
879                 ast_log(LOG_ERROR, "Out of memory\n");
880                 return 0;
881         }
882         stringp=copy;
883         piece = strsep(&stringp, ",");
884         while(piece) {
885                 if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
886                         /* Range */
887                 } else if (sscanf(piece, "%d", &start)) {
888                         /* Just one */
889                         finish = start;
890                 } else {
891                         ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.  Using '0'\n", s,piece);
892                         return 0;
893                 }
894                 piece = strsep(&stringp, ",");
895
896                 for (x=start;x<=finish;x++) {
897                         if ((x > 63) || (x < 0)) {
898                                 ast_log(LOG_WARNING, "Ignoring invalid group %d\n", x);
899                                 break;
900                         }
901                         group |= (1 << x);
902                 }
903         }
904         return group;
905 }
906
907 static int __unload_module(void)
908 {
909         struct ast_modem_pvt *p, *pl;
910         /* First, take us out of the channel loop */
911         ast_channel_unregister(&modem_tech);
912         if (!ast_mutex_lock(&iflock)) {
913                 /* Hangup all interfaces if they have an owner */
914                 p = iflist;
915                 while(p) {
916                         if (p->owner)
917                                 ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
918                         p = p->next;
919                 }
920                 iflist = NULL;
921                 ast_mutex_unlock(&iflock);
922         } else {
923                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
924                 return -1;
925         }
926         if (!ast_mutex_lock(&monlock)) {
927                 if (monitor_thread != AST_PTHREADT_NULL && monitor_thread != AST_PTHREADT_STOP) {
928                         pthread_cancel(monitor_thread);
929                         pthread_join(monitor_thread, NULL);
930                 }
931                 monitor_thread = AST_PTHREADT_STOP;
932                 ast_mutex_unlock(&monlock);
933         } else {
934                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
935                 return -1;
936         }
937
938         if (!ast_mutex_lock(&iflock)) {
939                 /* Destroy all the interfaces and free their memory */
940                 p = iflist;
941                 while(p) {
942                         /* Close the socket, assuming it's real */
943                         if (p->fd > -1)
944                                 close(p->fd);
945                         pl = p;
946                         p = p->next;
947                         /* Free associated memory */
948                         free(pl);
949                 }
950                 iflist = NULL;
951                 ast_mutex_unlock(&iflock);
952         } else {
953                 ast_log(LOG_WARNING, "Unable to lock the monitor\n");
954                 return -1;
955         }
956                 
957         return 0;
958 }
959
960 int unload_module()
961 {
962         return __unload_module();
963 }
964
965 int load_module()
966 {
967         struct ast_config *cfg;
968         struct ast_variable *v;
969         struct ast_modem_pvt *tmp;
970         char driver[80];
971         cfg = ast_config_load(config);
972
973         /* We *must* have a config file otherwise stop immediately */
974         if (!cfg) {
975                 ast_log(LOG_ERROR, "Unable to load config %s\n", config);
976                 return -1;
977         }
978         if (ast_mutex_lock(&iflock)) {
979                 /* It's a little silly to lock it, but we mind as well just to be sure */
980                 ast_log(LOG_ERROR, "Unable to lock interface list???\n");
981                 return -1;
982         }
983         v = ast_variable_browse(cfg, "interfaces");
984         while(v) {
985                 /* Create the interface list */
986                 if (!strcasecmp(v->name, "device")) {
987                                 tmp = mkif(v->value);
988                                 if (tmp) {
989                                         tmp->next = iflist;
990                                         iflist = tmp;
991                                         
992                                 } else {
993                                         ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
994                                         ast_config_destroy(cfg);
995                                         ast_mutex_unlock(&iflock);
996                                         __unload_module();
997                                         return -1;
998                                 }
999                 } else if (!strcasecmp(v->name, "driver")) {
1000                         snprintf(driver, sizeof(driver), "chan_modem_%s.so", v->value);
1001                         if (option_verbose > 1) 
1002                                 ast_verbose(VERBOSE_PREFIX_2 "Loading modem driver %s", driver);
1003                                 
1004                         if (ast_load_resource(driver)) {
1005                                 ast_log(LOG_ERROR, "Failed to load driver %s\n", driver);
1006                                 ast_config_destroy(cfg);
1007                                 ast_mutex_unlock(&iflock);
1008                                 __unload_module();
1009                                 return -1;
1010                         }
1011                 } else if (!strcasecmp(v->name, "mode")) {
1012                         if (!strncasecmp(v->value, "ri", 2)) 
1013                                 gmode = MODEM_MODE_WAIT_RING;
1014                         else if (!strncasecmp(v->value, "im", 2))
1015                                 gmode = MODEM_MODE_IMMEDIATE;
1016                         else if (!strncasecmp(v->value, "an", 2))
1017                                 gmode = MODEM_MODE_WAIT_ANSWER;
1018                         else
1019                                 ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);
1020                 } else if (!strcasecmp(v->name, "stripmsd")) {
1021                         stripmsd = atoi(v->value);
1022                 } else if (!strcasecmp(v->name, "type")) {
1023                         strncpy(mtype, v->value, sizeof(mtype)-1);
1024                 } else if (!strcasecmp(v->name, "initstr")) {
1025                         strncpy(initstr, v->value, sizeof(initstr)-1);
1026                 } else if (!strcasecmp(v->name, "dialtype")) {
1027                         dialtype = toupper(v->value[0]);
1028                 } else if (!strcasecmp(v->name, "context")) {
1029                         strncpy(context, v->value, sizeof(context)-1);
1030                 } else if (!strcasecmp(v->name, "msn")) {
1031                         strncpy(msn, v->value, sizeof(msn)-1);
1032                 } else if (!strcasecmp(v->name, "incomingmsn")) {
1033                         strncpy(incomingmsn, v->value, sizeof(incomingmsn)-1);
1034                 } else if (!strcasecmp(v->name, "dtmfmode")) {
1035                         char tmp[80];
1036                         char *alt;
1037                         strncpy(tmp, v->value, sizeof(tmp) - 1);
1038                         alt = strchr(tmp, '/');
1039                         if (!strcasecmp(tmp, "none"))
1040                                 dtmfmode=MODEM_DTMF_NONE;
1041                         else if (!strcasecmp(tmp, "asterisk"))
1042                                 dtmfmode = MODEM_DTMF_AST;
1043                         else if (!strcasecmp(tmp, "i4l"))
1044                                 dtmfmode = MODEM_DTMF_I4L;
1045                         else {
1046                                 ast_log(LOG_WARNING, "Unknown dtmf detection mode '%s', using 'asterisk'\n", v->value);
1047                                 dtmfmode = MODEM_DTMF_AST;
1048                         }
1049                         if (alt) {
1050                                 if (!strcasecmp(alt, "none"))
1051                                         dtmfmodegen=MODEM_DTMF_NONE;
1052                                 else if (!strcasecmp(alt, "asterisk"))
1053                                         dtmfmodegen = MODEM_DTMF_AST;
1054                                 else if (!strcasecmp(alt, "i4l"))
1055                                         dtmfmodegen = MODEM_DTMF_I4L;
1056                                 else if (!strcasecmp(alt, "both"))
1057                                         dtmfmodegen = MODEM_DTMF_I4L | MODEM_DTMF_AST;
1058                                 else {
1059                                         ast_log(LOG_WARNING, "Unknown dtmf generation mode '%s', using 'asterisk'\n", v->value);
1060                                         dtmfmodegen = MODEM_DTMF_AST;
1061                                 }
1062                         } else
1063                                 dtmfmodegen = dtmfmode;
1064                 } else if (!strcasecmp(v->name, "outgoingmsn")) {
1065                         strncpy(outgoingmsn, v->value, sizeof(outgoingmsn)-1);
1066                 } else if (!strcasecmp(v->name, "language")) {
1067                         strncpy(language, v->value, sizeof(language)-1);
1068                 } else if (!strcasecmp(v->name, "group")) {
1069                         cur_group = get_group(v->value);
1070                 }
1071                 v = v->next;
1072         }
1073         ast_mutex_unlock(&iflock);
1074         if (ast_channel_register(&modem_tech)) {
1075                 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
1076                 ast_config_destroy(cfg);
1077                 __unload_module();
1078                 return -1;
1079         }
1080         ast_config_destroy(cfg);
1081         /* And start the monitor for the first time */
1082         restart_monitor();
1083         return 0;
1084 }
1085
1086 int usecount(void)
1087 {
1088         int res;
1089         ast_mutex_lock(&usecnt_lock);
1090         res = usecnt;
1091         ast_mutex_unlock(&usecnt_lock);
1092         return res;
1093 }
1094
1095 char *description()
1096 {
1097         return (char *) desc;
1098 }
1099
1100 char *key()
1101 {
1102         return ASTERISK_GPL_KEY;
1103 }
1104