Whentohangup is in seconds, not milliseconds
[asterisk/asterisk.git] / channel.c
1  /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Channel Management
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 <stdlib.h>
16 #include <pthread.h>
17 #include <string.h>
18 #include <sys/time.h>
19 #include <signal.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <math.h>                       /* For PI */
23 #include <asterisk/pbx.h>
24 #include <asterisk/frame.h>
25 #include <asterisk/sched.h>
26 #include <asterisk/options.h>
27 #include <asterisk/channel.h>
28 #include <asterisk/channel_pvt.h>
29 #include <asterisk/logger.h>
30 #include <asterisk/file.h>
31 #include <asterisk/translate.h>
32 #include <asterisk/manager.h>
33 #include <asterisk/chanvars.h>
34 #include <asterisk/linkedlists.h>
35 #include <asterisk/indications.h>
36 #include <asterisk/monitor.h>
37 #include <asterisk/causes.h>
38 #ifdef ZAPTEL_OPTIMIZATIONS
39 #include <sys/ioctl.h>
40 #include <linux/zaptel.h>
41 #endif
42
43 /* uncomment if you have problems with 'monitoring' synchronized files */
44 #if 0
45 #define MONITOR_CONSTANT_DELAY
46 #define MONITOR_DELAY   150 * 8         /* 150 ms of MONITORING DELAY */
47 #endif
48
49 static int shutting_down = 0;
50 static int uniqueint = 0;
51
52 /* XXX Lock appropriately in more functions XXX */
53
54 struct chanlist {
55         char type[80];
56         char description[80];
57         int capabilities;
58         struct ast_channel * (*requester)(char *type, int format, void *data);
59         int (*devicestate)(void *data);
60         struct chanlist *next;
61 } *backends = NULL;
62 struct ast_channel *channels = NULL;
63
64 /* Protect the channel list (highly unlikely that two things would change
65    it at the same time, but still! */
66    
67 static ast_mutex_t chlock = AST_MUTEX_INITIALIZER;
68
69 int ast_check_hangup(struct ast_channel *chan)
70 {
71 time_t  myt;
72
73           /* if soft hangup flag, return true */
74         if (chan->_softhangup) return 1;
75           /* if no private structure, return true */
76         if (!chan->pvt->pvt) return 1;
77           /* if no hangup scheduled, just return here */
78         if (!chan->whentohangup) return 0;
79         time(&myt); /* get current time */
80           /* return, if not yet */
81         if (chan->whentohangup > myt) return 0;
82         chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
83         return 1;
84 }
85
86 static int ast_check_hangup_locked(struct ast_channel *chan)
87 {
88         int res;
89         ast_mutex_lock(&chan->lock);
90         res = ast_check_hangup(chan);
91         ast_mutex_unlock(&chan->lock);
92         return res;
93 }
94
95 void ast_begin_shutdown(int hangup)
96 {
97         struct ast_channel *c;
98         shutting_down = 1;
99         if (hangup) {
100                 ast_mutex_lock(&chlock);
101                 c = channels;
102                 while(c) {
103                         ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
104                         c = c->next;
105                 }
106                 ast_mutex_unlock(&chlock);
107         }
108 }
109
110 int ast_active_channels(void)
111 {
112         struct ast_channel *c;
113         int cnt = 0;
114         ast_mutex_lock(&chlock);
115         c = channels;
116         while(c) {
117                 cnt++;
118                 c = c->next;
119         }
120         ast_mutex_unlock(&chlock);
121         return cnt;
122 }
123
124 void ast_cancel_shutdown(void)
125 {
126         shutting_down = 0;
127 }
128
129 int ast_shutting_down(void)
130 {
131         return shutting_down;
132 }
133
134 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
135 {
136 time_t  myt;
137
138         time(&myt);
139         if (offset)
140           chan->whentohangup = myt + offset;
141         else
142           chan->whentohangup = 0;
143         return;
144 }
145
146 int ast_channel_register(char *type, char *description, int capabilities,
147                 struct ast_channel *(*requester)(char *type, int format, void *data))
148 {
149     return ast_channel_register_ex(type, description, capabilities, requester, NULL);
150 }
151
152 int ast_channel_register_ex(char *type, char *description, int capabilities,
153                 struct ast_channel *(*requester)(char *type, int format, void *data),
154                 int (*devicestate)(void *data))
155 {
156         struct chanlist *chan, *last=NULL;
157         if (ast_mutex_lock(&chlock)) {
158                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
159                 return -1;
160         }
161         chan = backends;
162         while(chan) {
163                 if (!strcasecmp(type, chan->type)) {
164                         ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
165                         ast_mutex_unlock(&chlock);
166                         return -1;
167                 }
168                 last = chan;
169                 chan = chan->next;
170         }
171         chan = malloc(sizeof(struct chanlist));
172         if (!chan) {
173                 ast_log(LOG_WARNING, "Out of memory\n");
174                 ast_mutex_unlock(&chlock);
175                 return -1;
176         }
177         strncpy(chan->type, type, sizeof(chan->type)-1);
178         strncpy(chan->description, description, sizeof(chan->description)-1);
179         chan->capabilities = capabilities;
180         chan->requester = requester;
181         chan->devicestate = devicestate;
182         chan->next = NULL;
183         if (last)
184                 last->next = chan;
185         else
186                 backends = chan;
187         if (option_debug)
188                 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
189         else if (option_verbose > 1)
190                 ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
191         ast_mutex_unlock(&chlock);
192         return 0;
193 }
194
195 char *ast_state2str(int state)
196 {
197         /* XXX Not reentrant XXX */
198         static char localtmp[256];
199         switch(state) {
200         case AST_STATE_DOWN:
201                 return "Down";
202         case AST_STATE_RESERVED:
203                 return "Rsrvd";
204         case AST_STATE_OFFHOOK:
205                 return "OffHook";
206         case AST_STATE_DIALING:
207                 return "Dialing";
208         case AST_STATE_RING:
209                 return "Ring";
210         case AST_STATE_RINGING:
211                 return "Ringing";
212         case AST_STATE_UP:
213                 return "Up";
214         case AST_STATE_BUSY:
215                 return "Busy";
216         default:
217                 snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
218                 return localtmp;
219         }
220 }
221
222
223 int ast_best_codec(int fmts)
224 {
225         /* This just our opinion, expressed in code.  We are asked to choose
226            the best codec to use, given no information */
227         int x;
228         static int prefs[] = 
229         {
230                 /* Okay, ulaw is used by all telephony equipment, so start with it */
231                 AST_FORMAT_ULAW,
232                 /* Unless of course, you're a silly European, so then prefer ALAW */
233                 AST_FORMAT_ALAW,
234                 /* Okay, well, signed linear is easy to translate into other stuff */
235                 AST_FORMAT_SLINEAR,
236                 /* G.726 is standard ADPCM */
237                 AST_FORMAT_G726,
238                 /* ADPCM has great sound quality and is still pretty easy to translate */
239                 AST_FORMAT_ADPCM,
240                 /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to
241                    translate and sounds pretty good */
242                 AST_FORMAT_GSM,
243                 /* iLBC is not too bad */
244                 AST_FORMAT_ILBC,
245                 /* Speex is free, but computationally more expensive than GSM */
246                 AST_FORMAT_SPEEX,
247                 /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
248                    to use it */
249                 AST_FORMAT_LPC10,
250                 /* G.729a is faster than 723 and slightly less expensive */
251                 AST_FORMAT_G729A,
252                 /* Down to G.723.1 which is proprietary but at least designed for voice */
253                 AST_FORMAT_G723_1,
254         };
255         
256         
257         for (x=0;x<sizeof(prefs) / sizeof(prefs[0]); x++)
258                 if (fmts & prefs[x])
259                         return prefs[x];
260         ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
261         return 0;
262 }
263
264 struct ast_channel *ast_channel_alloc(int needqueue)
265 {
266         struct ast_channel *tmp;
267         struct ast_channel_pvt *pvt;
268         int x;
269         int flags;
270         struct varshead *headp;        
271                 
272         
273         /* If shutting down, don't allocate any new channels */
274         if (shutting_down)
275                 return NULL;
276         ast_mutex_lock(&chlock);
277         tmp = malloc(sizeof(struct ast_channel));
278         if (tmp) {
279                 memset(tmp, 0, sizeof(struct ast_channel));
280                 pvt = malloc(sizeof(struct ast_channel_pvt));
281                 if (pvt) {
282                         memset(pvt, 0, sizeof(struct ast_channel_pvt));
283                         tmp->sched = sched_context_create();
284                         if (tmp->sched) {
285                                 for (x=0;x<AST_MAX_FDS - 1;x++)
286                                         tmp->fds[x] = -1;
287                                 if (needqueue &&  
288                                         pipe(pvt->alertpipe)) {
289                                         ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
290                                         free(pvt);
291                                         free(tmp);
292                                         tmp = NULL;
293                                         pvt = NULL;
294                                 } else {
295                                         /* Make sure we've got it done right if they don't */
296                                         if (needqueue) {
297                                                 flags = fcntl(pvt->alertpipe[0], F_GETFL);
298                                                 fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
299                                                 flags = fcntl(pvt->alertpipe[1], F_GETFL);
300                                                 fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
301                                         } else
302                                                 pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
303 #ifdef ZAPTEL_OPTIMIZATIONS
304                                         tmp->timingfd = open("/dev/zap/timer", O_RDWR);
305 #else
306                                         tmp->timingfd = -1;                                     
307 #endif
308                                         /* Always watch the alertpipe */
309                                         tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
310                                         /* And timing pipe */
311                                         tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
312                                         strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
313                                         tmp->pvt = pvt;
314                                         /* Initial state */
315                                         tmp->_state = AST_STATE_DOWN;
316                                         tmp->stack = -1;
317                                         tmp->streamid = -1;
318                                         tmp->appl = NULL;
319                                         tmp->data = NULL;
320                                         tmp->fin = 0;
321                                         tmp->fout = 0;
322                                         snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
323                                         headp=&tmp->varshead;
324                                         ast_mutex_init(&tmp->lock);
325                                         AST_LIST_HEAD_INIT(headp);
326                                         tmp->vars=ast_var_assign("tempvar","tempval");
327                                         AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
328                                         strncpy(tmp->context, "default", sizeof(tmp->context)-1);
329                                         strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
330                                         strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
331                                         tmp->priority=1;
332                                         tmp->amaflags = ast_default_amaflags;
333                                         strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
334                                         tmp->next = channels;
335                                         channels= tmp;
336                                 }
337                         } else {
338                                 ast_log(LOG_WARNING, "Unable to create schedule context\n");
339                                 free(tmp);
340                                 tmp = NULL;
341                         }
342                 } else {
343                         ast_log(LOG_WARNING, "Out of memory\n");
344                         free(tmp);
345                         tmp = NULL;
346                 }
347         } else 
348                 ast_log(LOG_WARNING, "Out of memory\n");
349         ast_mutex_unlock(&chlock);
350         return tmp;
351 }
352
353 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int lock)
354 {
355         struct ast_frame *f;
356         struct ast_frame *prev, *cur;
357         int blah = 1;
358         int qlen = 0;
359         /* Build us a copy and free the original one */
360         f = ast_frdup(fin);
361         if (!f) {
362                 ast_log(LOG_WARNING, "Unable to duplicate frame\n");
363                 return -1;
364         }
365         if (lock)
366                 ast_mutex_lock(&chan->lock);
367         prev = NULL;
368         cur = chan->pvt->readq;
369         while(cur) {
370                 prev = cur;
371                 cur = cur->next;
372                 qlen++;
373         }
374         /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
375         if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
376                 if (fin->frametype != AST_FRAME_VOICE) {
377                         ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
378                         CRASH;
379                 } else {
380                         ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
381                         ast_frfree(f);
382                         if (lock)
383                                 ast_mutex_unlock(&chan->lock);
384                         return 0;
385                 }
386         }
387         if (prev)
388                 prev->next = f;
389         else
390                 chan->pvt->readq = f;
391         if (chan->pvt->alertpipe[1] > -1) {
392                 if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
393                         ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
394                                 chan->name, f->frametype, f->subclass, qlen, strerror(errno));
395         } else if (chan->blocking) {
396                 pthread_kill(chan->blocker, SIGURG);
397         }
398         if (lock)
399                 ast_mutex_unlock(&chan->lock);
400         return 0;
401 }
402
403 int ast_queue_hangup(struct ast_channel *chan, int lock)
404 {
405         struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
406         chan->_softhangup |= AST_SOFTHANGUP_DEV;
407         return ast_queue_frame(chan, &f, lock);
408 }
409
410 int ast_queue_control(struct ast_channel *chan, int control, int lock)
411 {
412         struct ast_frame f = { AST_FRAME_CONTROL, };
413         f.subclass = control;
414         return ast_queue_frame(chan, &f, lock);
415 }
416
417 int ast_channel_defer_dtmf(struct ast_channel *chan)
418 {
419         int pre = 0;
420         if (chan) {
421                 pre = chan->deferdtmf;
422                 chan->deferdtmf = 1;
423         }
424         return pre;
425 }
426
427 void ast_channel_undefer_dtmf(struct ast_channel *chan)
428 {
429         if (chan)
430                 chan->deferdtmf = 0;
431 }
432
433 struct ast_channel *ast_channel_walk(struct ast_channel *prev)
434 {
435         struct ast_channel *l, *ret=NULL;
436         ast_mutex_lock(&chlock);
437         l = channels;
438         if (!prev) {
439                 ast_mutex_unlock(&chlock);
440                 return l;
441         }
442         while(l) {
443                 if (l == prev)
444                         ret = l->next;
445                 l = l->next;
446         }
447         ast_mutex_unlock(&chlock);
448         return ret;
449         
450 }
451
452 int ast_safe_sleep_conditional( struct ast_channel *chan, int ms,
453                                                                 int (*cond)(void*), void *data )
454 {
455         struct ast_frame *f;
456
457         while(ms > 0) {
458                 if( cond && ((*cond)(data) == 0 ) )
459                         return 0;
460                 ms = ast_waitfor(chan, ms);
461                 if (ms <0)
462                         return -1;
463                 if (ms > 0) {
464                         f = ast_read(chan);
465                         if (!f)
466                                 return -1;
467                         ast_frfree(f);
468                 }
469         }
470         return 0;
471 }
472
473 int ast_safe_sleep(struct ast_channel *chan, int ms)
474 {
475         struct ast_frame *f;
476         while(ms > 0) {
477                 ms = ast_waitfor(chan, ms);
478                 if (ms <0)
479                         return -1;
480                 if (ms > 0) {
481                         f = ast_read(chan);
482                         if (!f)
483                                 return -1;
484                         ast_frfree(f);
485                 }
486         }
487         return 0;
488 }
489
490 void ast_channel_free(struct ast_channel *chan)
491 {
492         struct ast_channel *last=NULL, *cur;
493         int fd;
494         struct ast_var_t *vardata;
495         struct ast_frame *f, *fp;
496         struct varshead *headp;
497         char name[AST_CHANNEL_NAME];
498         
499         headp=&chan->varshead;
500         
501         ast_mutex_lock(&chlock);
502         cur = channels;
503         while(cur) {
504                 if (cur == chan) {
505                         if (last)
506                                 last->next = cur->next;
507                         else
508                                 channels = cur->next;
509                         break;
510                 }
511                 last = cur;
512                 cur = cur->next;
513         }
514         if (!cur)
515                 ast_log(LOG_WARNING, "Unable to find channel in list\n");
516         if (chan->pvt->pvt)
517                 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
518
519         strncpy(name, chan->name, sizeof(name)-1);
520         
521         /* Stop monitoring */
522         if (chan->monitor) {
523                 chan->monitor->stop( chan, 0 );
524         }
525
526         /* Free translatosr */
527         if (chan->pvt->readtrans)
528                 ast_translator_free_path(chan->pvt->readtrans);
529         if (chan->pvt->writetrans)
530                 ast_translator_free_path(chan->pvt->writetrans);
531         if (chan->pbx) 
532                 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
533         if (chan->dnid)
534                 free(chan->dnid);
535         if (chan->callerid)
536                 free(chan->callerid);   
537         if (chan->ani)
538                 free(chan->ani);
539         if (chan->rdnis)
540                 free(chan->rdnis);
541         ast_mutex_destroy(&chan->lock);
542         /* Close pipes if appropriate */
543         if ((fd = chan->pvt->alertpipe[0]) > -1)
544                 close(fd);
545         if ((fd = chan->pvt->alertpipe[1]) > -1)
546                 close(fd);
547         if ((fd = chan->timingfd) > -1)
548                 close(fd);
549         f = chan->pvt->readq;
550         chan->pvt->readq = NULL;
551         while(f) {
552                 fp = f;
553                 f = f->next;
554                 ast_frfree(fp);
555         }
556         
557         /* loop over the variables list, freeing all data and deleting list items */
558         /* no need to lock the list, as the channel is already locked */
559         
560         while (!AST_LIST_EMPTY(headp)) {           /* List Deletion. */
561                     vardata = AST_LIST_FIRST(headp);
562                     AST_LIST_REMOVE_HEAD(headp, entries);
563 //                  printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
564                     ast_var_delete(vardata);
565         }
566                                                          
567
568         free(chan->pvt);
569         chan->pvt = NULL;
570         free(chan);
571         ast_mutex_unlock(&chlock);
572
573         ast_device_state_changed(name);
574 }
575
576 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
577 {
578         int res = 0;
579         struct ast_frame f = { AST_FRAME_NULL };
580         if (option_debug)
581                 ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
582         /* Inform channel driver that we need to be hung up, if it cares */
583         chan->_softhangup |= cause;
584         ast_queue_frame(chan, &f, 0);
585         /* Interrupt any select call or such */
586         if (chan->blocking)
587                 pthread_kill(chan->blocker, SIGURG);
588         return res;
589 }
590
591 int ast_softhangup(struct ast_channel *chan, int cause)
592 {
593         int res;
594         ast_mutex_lock(&chan->lock);
595         res = ast_softhangup_nolock(chan, cause);
596         ast_mutex_unlock(&chan->lock);
597         return res;
598 }
599
600 static void free_translation(struct ast_channel *clone)
601 {
602         if (clone->pvt->writetrans)
603                 ast_translator_free_path(clone->pvt->writetrans);
604         if (clone->pvt->readtrans)
605                 ast_translator_free_path(clone->pvt->readtrans);
606         clone->pvt->writetrans = NULL;
607         clone->pvt->readtrans = NULL;
608         clone->pvt->rawwriteformat = clone->nativeformats;
609         clone->pvt->rawreadformat = clone->nativeformats;
610 }
611
612 int ast_hangup(struct ast_channel *chan)
613 {
614         int res = 0;
615         /* Don't actually hang up a channel that will masquerade as someone else, or
616            if someone is going to masquerade as us */
617         ast_mutex_lock(&chan->lock);
618         if (chan->masq) {
619                 if (ast_do_masquerade(chan, 1)) 
620                         ast_log(LOG_WARNING, "Failed to perform masquerade\n");
621         }
622
623         if (chan->masq) {
624                 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
625                 ast_mutex_unlock(&chan->lock);
626                 return 0;
627         }
628         /* If this channel is one which will be masqueraded into something, 
629            mark it as a zombie already, so we know to free it later */
630         if (chan->masqr) {
631                 chan->zombie=1;
632                 ast_mutex_unlock(&chan->lock);
633                 return 0;
634         }
635         free_translation(chan);
636         if (chan->stream)
637                 ast_stopstream(chan);
638         if (chan->sched)
639                 sched_context_destroy(chan->sched);
640         /* Clear any tone stuff remaining */
641         if (chan->generatordata)
642                 chan->generator->release(chan, chan->generatordata);
643         chan->generatordata = NULL;
644         chan->generator = NULL;
645         if (chan->cdr) {
646                 /* End the CDR if it hasn't already */
647                 ast_cdr_end(chan->cdr);
648                 /* Post and Free the CDR */
649                 ast_cdr_post(chan->cdr);
650                 ast_cdr_free(chan->cdr);
651         }
652         if (chan->blocking) {
653                 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
654                                         "is blocked by thread %ld in procedure %s!  Expect a failure\n",
655                                         (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
656                 CRASH;
657         }
658         if (!chan->zombie) {
659                 if (option_debug)
660                         ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
661                 if (chan->pvt->hangup)
662                         res = chan->pvt->hangup(chan);
663         } else
664                 if (option_debug)
665                         ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
666                         
667         ast_mutex_unlock(&chan->lock);
668         manager_event(EVENT_FLAG_CALL, "Hangup", 
669                         "Channel: %s\r\n"
670                         "Uniqueid: %s\r\n",
671                         chan->name, chan->uniqueid);
672         ast_channel_free(chan);
673         return res;
674 }
675
676 void ast_channel_unregister(char *type)
677 {
678         struct chanlist *chan, *last=NULL;
679         if (option_debug)
680                 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
681         if (ast_mutex_lock(&chlock)) {
682                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
683                 return;
684         }
685         if (option_verbose > 1)
686                 ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type);
687
688         chan = backends;
689         while(chan) {
690                 if (!strcasecmp(chan->type, type)) {
691                         if (last)
692                                 last->next = chan->next;
693                         else
694                                 backends = backends->next;
695                         free(chan);
696                         ast_mutex_unlock(&chlock);
697                         return;
698                 }
699                 last = chan;
700                 chan = chan->next;
701         }
702         ast_mutex_unlock(&chlock);
703 }
704
705 int ast_answer(struct ast_channel *chan)
706 {
707         int res = 0;
708         /* Stop if we're a zombie or need a soft hangup */
709         if (chan->zombie || ast_check_hangup(chan)) 
710                 return -1;
711         switch(chan->_state) {
712         case AST_STATE_RINGING:
713         case AST_STATE_RING:
714                 ast_mutex_lock(&chan->lock);
715                 if (chan->pvt->answer)
716                         res = chan->pvt->answer(chan);
717                 ast_mutex_unlock(&chan->lock);
718                 ast_setstate(chan, AST_STATE_UP);
719                 if (chan->cdr)
720                         ast_cdr_answer(chan->cdr);
721                 return res;
722                 break;
723         case AST_STATE_UP:
724                 if (chan->cdr)
725                         ast_cdr_answer(chan->cdr);
726                 break;
727         }
728         return 0;
729 }
730
731 void ast_deactivate_generator(struct ast_channel *chan)
732 {
733         if (chan->generatordata) {
734                 if (chan->generator && chan->generator->release) 
735                         chan->generator->release(chan, chan->generatordata);
736                 chan->generatordata = NULL;
737                 chan->generator = NULL;
738                 chan->writeinterrupt = 0;
739         }
740 }
741
742 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
743 {
744         if (chan->generatordata) {
745                 if (chan->generator && chan->generator->release)
746                         chan->generator->release(chan, chan->generatordata);
747                 chan->generatordata = NULL;
748         }
749         ast_prod(chan);
750         if ((chan->generatordata = gen->alloc(chan, params))) {
751                 chan->generator = gen;
752         } else {
753                 return -1;
754         }
755         return 0;
756 }
757
758 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
759 {
760         /* Wait for x amount of time on a file descriptor to have input.  */
761         struct timeval tv;
762         fd_set rfds, efds;
763         int res;
764         int x, max=-1;
765         int winner = -1;
766         
767         tv.tv_sec = *ms / 1000;
768         tv.tv_usec = (*ms % 1000) * 1000;
769         FD_ZERO(&rfds);
770         FD_ZERO(&efds);
771         for (x=0;x<n;x++) {
772                 if (fds[x] > -1) {
773                         FD_SET(fds[x], &rfds);
774                         FD_SET(fds[x], &efds);
775                         if (fds[x] > max)
776                                 max = fds[x];
777                 }
778         }
779         if (*ms >= 0)
780                 res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
781         else
782                 res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
783
784         if (res < 0) {
785                 /* Simulate a timeout if we were interrupted */
786                 if (errno != EINTR)
787                         *ms = -1;
788                 else
789                         *ms = 0;
790                 return -1;
791         }
792
793         for (x=0;x<n;x++) {
794                 if ((fds[x] > -1) && (FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && (winner < 0)) {
795                         if (exception)
796                                 *exception = FD_ISSET(fds[x], &efds);
797                         winner = fds[x];
798                 }
799         }
800         *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
801         return winner;
802 }
803
804 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, 
805         int *exception, int *outfd, int *ms)
806 {
807         /* Wait for x amount of time on a file descriptor to have input.  */
808         struct timeval tv;
809         fd_set rfds, efds;
810         int res;
811         int x, y, max=-1;
812         time_t now = 0;
813         long whentohangup = 0, havewhen = 0, diff;
814         struct ast_channel *winner = NULL;
815         if (outfd)
816                 *outfd = -99999;
817         if (exception)
818                 *exception = 0;
819         
820         /* Perform any pending masquerades */
821         for (x=0;x<n;x++) {
822                 ast_mutex_lock(&c[x]->lock);
823                 if (c[x]->whentohangup) {
824                         if (!havewhen)
825                                 time(&now);
826                         diff = c[x]->whentohangup - now;
827                         if (!havewhen || (diff < whentohangup)) {
828                                 havewhen++;
829                                 whentohangup = diff;
830                         }
831                 }
832                 if (c[x]->masq) {
833                         if (ast_do_masquerade(c[x], 1)) {
834                                 ast_log(LOG_WARNING, "Masquerade failed\n");
835                                 *ms = -1;
836                                 ast_mutex_unlock(&c[x]->lock);
837                                 return NULL;
838                         }
839                 }
840                 ast_mutex_unlock(&c[x]->lock);
841         }
842         
843         tv.tv_sec = *ms / 1000;
844         tv.tv_usec = (*ms % 1000) * 1000;
845         
846         if (havewhen) {
847                 if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
848                         tv.tv_sec = whentohangup;
849                         tv.tv_usec = 0;
850                 }
851         }
852         FD_ZERO(&rfds);
853         FD_ZERO(&efds);
854
855         for (x=0;x<n;x++) {
856                 for (y=0;y<AST_MAX_FDS;y++) {
857                         if (c[x]->fds[y] > -1) {
858                                 FD_SET(c[x]->fds[y], &rfds);
859                                 FD_SET(c[x]->fds[y], &efds);
860                                 if (c[x]->fds[y] > max)
861                                         max = c[x]->fds[y];
862                         }
863                 }
864                 CHECK_BLOCKING(c[x]);
865         }
866         for (x=0;x<nfds; x++) {
867                 FD_SET(fds[x], &rfds);
868                 FD_SET(fds[x], &efds);
869                 if (fds[x] > max)
870                         max = fds[x];
871         }
872         if ((*ms >= 0) || (havewhen))
873                 res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
874         else
875                 res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
876
877         if (res < 0) {
878                 for (x=0;x<n;x++) 
879                         c[x]->blocking = 0;
880                 /* Simulate a timeout if we were interrupted */
881                 if (errno != EINTR)
882                         *ms = -1;
883                 else {
884                         /* Just an interrupt */
885 #if 0
886                         *ms = 0;
887 #endif                  
888                 }
889                 return NULL;
890         }
891
892         if (havewhen)
893                 time(&now);
894         for (x=0;x<n;x++) {
895                 c[x]->blocking = 0;
896                 if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
897                         c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
898                         if (!winner)
899                                 winner = c[x];
900                 }
901                 for (y=0;y<AST_MAX_FDS;y++) {
902                         if (c[x]->fds[y] > -1) {
903                                 if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
904                                         /* Set exception flag if appropriate */
905                                         if (FD_ISSET(c[x]->fds[y], &efds))
906                                                 c[x]->exception = 1;
907                                         c[x]->fdno = y;
908                                         winner = c[x];
909                                 }
910                         }
911                 }
912         }
913         for (x=0;x<nfds;x++) {
914                 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) {
915                         if (outfd)
916                                 *outfd = fds[x];
917                         if (FD_ISSET(fds[x], &efds) && exception)
918                                 *exception = 1;
919                         winner = NULL;
920                 }
921         }
922         *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
923         return winner;
924 }
925
926 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
927 {
928         return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
929 }
930
931 int ast_waitfor(struct ast_channel *c, int ms)
932 {
933         struct ast_channel *chan;
934         int oldms = ms;
935         chan = ast_waitfor_n(&c, 1, &ms);
936         if (ms < 0) {
937                 if (oldms < 0)
938                         return 0;
939                 else
940                         return -1;
941         }
942         return ms;
943 }
944
945 char ast_waitfordigit(struct ast_channel *c, int ms)
946 {
947         /* XXX Should I be merged with waitfordigit_full XXX */
948         struct ast_frame *f;
949         char result = 0;
950         /* Stop if we're a zombie or need a soft hangup */
951         if (c->zombie || ast_check_hangup(c)) 
952                 return -1;
953         /* Wait for a digit, no more than ms milliseconds total. */
954         while(ms && !result) {
955                 ms = ast_waitfor(c, ms);
956                 if (ms < 0) /* Error */
957                         result = -1; 
958                 else if (ms > 0) {
959                         /* Read something */
960                         f = ast_read(c);
961                         if (f) {
962                                 if (f->frametype == AST_FRAME_DTMF) 
963                                         result = f->subclass;
964                                 ast_frfree(f);
965                         } else
966                                 result = -1;
967                 }
968         }
969         return result;
970 }
971
972 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
973 {
974         int res = -1;
975 #ifdef ZAPTEL_OPTIMIZATIONS
976         if (c->timingfd > -1) {
977                 if (!func) {
978                         samples = 0;
979                         data = 0;
980                 }
981                 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
982                 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
983                 c->timingfunc = func;
984                 c->timingdata = data;
985         }
986 #endif  
987         return res;
988 }
989 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audio, int ctrl)
990 {
991         struct ast_frame *f;
992         char result = 0;
993         struct ast_channel *rchan;
994         int outfd;
995         /* Stop if we're a zombie or need a soft hangup */
996         if (c->zombie || ast_check_hangup(c)) 
997                 return -1;
998         /* Wait for a digit, no more than ms milliseconds total. */
999         while(ms && !result) {
1000                 rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms);
1001                 if ((!rchan) && (outfd < 0) && (ms)) /* Error */
1002                         result = -1; 
1003                 else if (outfd > -1) {
1004                         result = 1;
1005                 } else if (rchan) {
1006                         /* Read something */
1007                         f = ast_read(c);
1008                         if (f) {
1009                                 if (f->frametype == AST_FRAME_DTMF) 
1010                                         result = f->subclass;
1011                                 ast_frfree(f);
1012                         } else
1013                                 result = -1;
1014                 }
1015         }
1016         return result;
1017 }
1018
1019 struct ast_frame *ast_read(struct ast_channel *chan)
1020 {
1021         struct ast_frame *f = NULL;
1022         int blah;
1023 #ifdef ZAPTEL_OPTIMIZATIONS
1024         int (*func)(void *);
1025         void *data;
1026 #endif
1027         static struct ast_frame null_frame = 
1028         {
1029                 AST_FRAME_NULL,
1030         };
1031         
1032         ast_mutex_lock(&chan->lock);
1033         if (chan->masq) {
1034                 if (ast_do_masquerade(chan, 1)) {
1035                         ast_log(LOG_WARNING, "Failed to perform masquerade\n");
1036                         f = NULL;
1037                 } else
1038                         f =  &null_frame;
1039                 ast_mutex_unlock(&chan->lock);
1040                 return f;
1041         }
1042
1043         /* Stop if we're a zombie or need a soft hangup */
1044         if (chan->zombie || ast_check_hangup(chan)) {
1045                 if (chan->generator)
1046                         ast_deactivate_generator(chan);
1047                 ast_mutex_unlock(&chan->lock);
1048                 return NULL;
1049         }
1050
1051         if (!chan->deferdtmf && strlen(chan->dtmfq)) {
1052                 /* We have DTMF that has been deferred.  Return it now */
1053                 chan->dtmff.frametype = AST_FRAME_DTMF;
1054                 chan->dtmff.subclass = chan->dtmfq[0];
1055                 /* Drop first digit */
1056                 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
1057                 ast_mutex_unlock(&chan->lock);
1058                 return &chan->dtmff;
1059         }
1060         
1061         /* Read and ignore anything on the alertpipe, but read only
1062            one sizeof(blah) per frame that we send from it */
1063         if (chan->pvt->alertpipe[0] > -1) {
1064                 read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
1065         }
1066 #ifdef ZAPTEL_OPTIMIZATIONS
1067         if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
1068                 chan->exception = 0;
1069                 blah = -1;
1070                 ioctl(chan->timingfd, ZT_TIMERACK, &blah);
1071                 func = chan->timingfunc;
1072                 data = chan->timingdata;
1073                 ast_mutex_unlock(&chan->lock);
1074                 if (func) {
1075 #if 0
1076                         ast_log(LOG_DEBUG, "Calling private function\n");
1077 #endif                  
1078                         func(data);
1079                 } else {
1080                         blah = 0;
1081                         ast_mutex_lock(&chan->lock);
1082                         ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
1083                         chan->timingdata = NULL;
1084                         ast_mutex_unlock(&chan->lock);
1085                 }
1086                 f =  &null_frame;
1087                 return f;
1088         }
1089 #endif
1090         /* Check for pending read queue */
1091         if (chan->pvt->readq) {
1092                 f = chan->pvt->readq;
1093                 chan->pvt->readq = f->next;
1094                 /* Interpret hangup and return NULL */
1095                 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
1096                         ast_frfree(f);
1097                         f = NULL;
1098                 }
1099         } else {
1100                 chan->blocker = pthread_self();
1101                 if (chan->exception) {
1102                         if (chan->pvt->exception) 
1103                                 f = chan->pvt->exception(chan);
1104                         else {
1105                                 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
1106                                 f = &null_frame;
1107                         }
1108                         /* Clear the exception flag */
1109                         chan->exception = 0;
1110                 } else
1111                 if (chan->pvt->read)
1112                         f = chan->pvt->read(chan);
1113                 else
1114                         ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
1115         }
1116
1117
1118         if (f && (f->frametype == AST_FRAME_VOICE)) {
1119                 if (!(f->subclass & chan->nativeformats)) {
1120                         /* This frame can't be from the current native formats -- drop it on the
1121                            floor */
1122                         ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
1123                         ast_frfree(f);
1124                         f = &null_frame;
1125                 } else {
1126                         if (chan->monitor && chan->monitor->read_stream ) {
1127 #ifndef MONITOR_CONSTANT_DELAY
1128                                 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
1129                                 if (jump >= 0) {
1130                                         if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
1131                                                 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
1132                                         chan->insmpl += jump + 2 * f->samples;
1133                                 } else
1134                                         chan->insmpl+= f->samples;
1135 #else
1136                                 int jump = chan->outsmpl - chan->insmpl;
1137                                 if (jump - MONITOR_DELAY >= 0) {
1138                                         if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
1139                                                 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
1140                                         chan->insmpl += jump;
1141                                 } else
1142                                         chan->insmpl += f->samples;
1143 #endif
1144                                 if (ast_writestream(chan->monitor->read_stream, f) < 0)
1145                                         ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
1146                         }
1147                         if (chan->pvt->readtrans) {
1148                                 f = ast_translate(chan->pvt->readtrans, f, 1);
1149                                 if (!f)
1150                                         f = &null_frame;
1151                         }
1152                 }
1153         }
1154
1155         /* Make sure we always return NULL in the future */
1156         if (!f) {
1157                 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1158                 if (chan->generator)
1159                         ast_deactivate_generator(chan);
1160                 /* End the CDR if appropriate */
1161                 if (chan->cdr)
1162                         ast_cdr_end(chan->cdr);
1163         } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
1164                 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
1165                         chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
1166                 else
1167                         ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
1168                 f = &null_frame;
1169         } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
1170                 /* Answer the CDR */
1171                 ast_setstate(chan, AST_STATE_UP);
1172                 ast_cdr_answer(chan->cdr);
1173         } 
1174         ast_mutex_unlock(&chan->lock);
1175
1176         /* Run any generator sitting on the line */
1177         if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
1178                 /* Mask generator data temporarily */
1179                 void *tmp;
1180                 int res;
1181                 tmp = chan->generatordata;
1182                 chan->generatordata = NULL;
1183                 res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
1184                 chan->generatordata = tmp;
1185                 if (res) {
1186                         ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
1187                         ast_deactivate_generator(chan);
1188                 }
1189         }
1190         if (chan->fin & 0x80000000)
1191                 ast_frame_dump(chan->name, f, "<<");
1192         if ((chan->fin & 0x7fffffff) == 0x7fffffff)
1193                 chan->fin &= 0x80000000;
1194         else
1195                 chan->fin++;
1196         return f;
1197 }
1198
1199 int ast_indicate(struct ast_channel *chan, int condition)
1200 {
1201         int res = -1;
1202         /* Stop if we're a zombie or need a soft hangup */
1203         if (chan->zombie || ast_check_hangup(chan)) 
1204                 return -1;
1205         ast_mutex_lock(&chan->lock);
1206         if (chan->pvt->indicate)
1207                 res = chan->pvt->indicate(chan, condition);
1208         ast_mutex_unlock(&chan->lock);
1209         if (!chan->pvt->indicate || res) {
1210                 /*
1211                  * Device does not support (that) indication, lets fake
1212                  * it by doing our own tone generation. (PM2002)
1213                  */
1214                 if (condition >= 0) {
1215                         const struct tone_zone_sound *ts = NULL;
1216                         switch (condition) {
1217                          case AST_CONTROL_RINGING:
1218                                 ts = ast_get_indication_tone(chan->zone, "ring");
1219                                 break;
1220                          case AST_CONTROL_BUSY:
1221                                 ts = ast_get_indication_tone(chan->zone, "busy");
1222                                 break;
1223                          case AST_CONTROL_CONGESTION:
1224                                 ts = ast_get_indication_tone(chan->zone, "congestion");
1225                                 break;
1226                         }
1227                         if (ts && ts->data[0]) {
1228                                 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
1229                                 ast_playtones_start(chan,0,ts->data, 1);
1230                                 res = 0;
1231                         } else if (condition == AST_CONTROL_PROGRESS) {
1232                                 /* ast_playtones_stop(chan); */
1233                         } else {
1234                                 /* not handled */
1235                                 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
1236                                 res = -1;
1237                         }
1238                 }
1239                 else ast_playtones_stop(chan);
1240         }
1241         return res;
1242 }
1243
1244 int ast_recvchar(struct ast_channel *chan, int timeout)
1245 {
1246         int res,ourto,c;
1247         struct ast_frame *f;
1248         
1249         ourto = timeout;
1250         for(;;)
1251            {
1252                 if (ast_check_hangup(chan)) return -1;
1253                 res = ast_waitfor(chan,ourto);
1254                 if (res <= 0) /* if timeout */
1255                    {
1256                         return 0;
1257                    }
1258                 ourto = res;
1259                 f = ast_read(chan);
1260                 if (f == NULL) return -1; /* if hangup */
1261                 if ((f->frametype == AST_FRAME_CONTROL) &&
1262                     (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */
1263                 if (f->frametype == AST_FRAME_TEXT)  /* if a text frame */
1264                    {
1265                         c = *((char *)f->data);  /* get the data */
1266                         ast_frfree(f);
1267                         return(c);
1268                    }
1269                 ast_frfree(f);
1270         }
1271 }
1272
1273 int ast_sendtext(struct ast_channel *chan, char *text)
1274 {
1275         int res = 0;
1276         /* Stop if we're a zombie or need a soft hangup */
1277         if (chan->zombie || ast_check_hangup(chan)) 
1278                 return -1;
1279         CHECK_BLOCKING(chan);
1280         if (chan->pvt->send_text)
1281                 res = chan->pvt->send_text(chan, text);
1282         chan->blocking = 0;
1283         return res;
1284 }
1285
1286 static int do_senddigit(struct ast_channel *chan, char digit)
1287 {
1288         int res = -1;
1289
1290         if (chan->pvt->send_digit)
1291                 res = chan->pvt->send_digit(chan, digit);
1292         if (!chan->pvt->send_digit || res) {
1293                 /*
1294                  * Device does not support DTMF tones, lets fake
1295                  * it by doing our own generation. (PM2002)
1296                  */
1297                 static const char* dtmf_tones[] = {
1298                         "!941+1336/100,!0/100", /* 0 */
1299                         "!697+1209/100,!0/100", /* 1 */
1300                         "!697+1336/100,!0/100", /* 2 */
1301                         "!697+1477/100,!0/100", /* 3 */
1302                         "!770+1209/100,!0/100", /* 4 */
1303                         "!770+1336/100,!0/100", /* 5 */
1304                         "!770+1477/100,!0/100", /* 6 */
1305                         "!852+1209/100,!0/100", /* 7 */
1306                         "!852+1336/100,!0/100", /* 8 */
1307                         "!852+1477/100,!0/100", /* 9 */
1308                         "!697+1633/100,!0/100", /* A */
1309                         "!770+1633/100,!0/100", /* B */
1310                         "!852+1633/100,!0/100", /* C */
1311                         "!941+1633/100,!0/100", /* D */
1312                         "!941+1209/100,!0/100", /* * */
1313                         "!941+1477/100,!0/100" };       /* # */
1314                 if (digit >= '0' && digit <='9')
1315                         ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
1316                 else if (digit >= 'A' && digit <= 'D')
1317                         ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
1318                 else if (digit == '*')
1319                         ast_playtones_start(chan,0,dtmf_tones[14], 0);
1320                 else if (digit == '#')
1321                         ast_playtones_start(chan,0,dtmf_tones[15], 0);
1322                 else {
1323                         /* not handled */
1324                         ast_log(LOG_WARNING, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
1325                         return -1;
1326                 }
1327         }
1328         return 0;
1329 }
1330
1331 int ast_prod(struct ast_channel *chan)
1332 {
1333         struct ast_frame a = { AST_FRAME_VOICE };
1334         char nothing[128];
1335         /* Send an empty audio frame to get things moving */
1336         if (chan->_state != AST_STATE_UP) {
1337                 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
1338                 a.subclass = chan->pvt->rawwriteformat;
1339                 a.data = nothing + AST_FRIENDLY_OFFSET;
1340                 if (ast_write(chan, &a))
1341                         ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
1342         }
1343         return 0;
1344 }
1345
1346 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
1347 {
1348         int res;
1349         if (!chan->pvt->write_video)
1350                 return 0;
1351         res = ast_write(chan, fr);
1352         if (!res)
1353                 res = 1;
1354         return res;
1355 }
1356
1357 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
1358 {
1359         int res = -1;
1360         struct ast_frame *f = NULL;
1361         /* Stop if we're a zombie or need a soft hangup */
1362         ast_mutex_lock(&chan->lock);
1363         if (chan->zombie || ast_check_hangup(chan))  {
1364                 ast_mutex_unlock(&chan->lock);
1365                 return -1;
1366         }
1367         /* Handle any pending masquerades */
1368         if (chan->masq) {
1369                 if (ast_do_masquerade(chan, 1)) {
1370                         ast_log(LOG_WARNING, "Failed to perform masquerade\n");
1371                         ast_mutex_unlock(&chan->lock);
1372                         return -1;
1373                 }
1374         }
1375         if (chan->masqr) {
1376                 ast_mutex_unlock(&chan->lock);
1377                 return 0;
1378         }
1379         if (chan->generatordata) {
1380                 if (chan->writeinterrupt)
1381                         ast_deactivate_generator(chan);
1382                 else {
1383                         ast_mutex_unlock(&chan->lock);
1384                         return 0;
1385                 }
1386         }
1387         if (chan->fout & 0x80000000)
1388                 ast_frame_dump(chan->name, fr, ">>");
1389         CHECK_BLOCKING(chan);
1390         switch(fr->frametype) {
1391         case AST_FRAME_CONTROL:
1392                 /* XXX Interpret control frames XXX */
1393                 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
1394                 break;
1395         case AST_FRAME_DTMF:
1396                 chan->blocking = 0;
1397                 ast_mutex_unlock(&chan->lock);
1398                 res = do_senddigit(chan,fr->subclass);
1399                 ast_mutex_lock(&chan->lock);
1400                 CHECK_BLOCKING(chan);
1401                 break;
1402         case AST_FRAME_TEXT:
1403                 if (chan->pvt->send_text)
1404                         res = chan->pvt->send_text(chan, (char *) fr->data);
1405                 break;
1406         case AST_FRAME_VIDEO:
1407                 /* XXX Handle translation of video codecs one day XXX */
1408                 if (chan->pvt->write_video)
1409                         res = chan->pvt->write_video(chan, fr);
1410                 else
1411                         res = 0;
1412                 break;
1413         default:
1414                 if (chan->pvt->write) {
1415                         if (chan->pvt->writetrans) {
1416                                 f = ast_translate(chan->pvt->writetrans, fr, 0);
1417                         } else
1418                                 f = fr;
1419                         if (f) {
1420                                 res = chan->pvt->write(chan, f);
1421                                 if( chan->monitor &&
1422                                                 chan->monitor->write_stream &&
1423                                                 f && ( f->frametype == AST_FRAME_VOICE ) ) {
1424 #ifndef MONITOR_CONSTANT_DELAY
1425                                         int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
1426                                         if (jump >= 0) {
1427                                                 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
1428                                                         ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
1429                                                 chan->outsmpl += jump + 2 * f->samples;
1430                                         } else
1431                                                 chan->outsmpl += f->samples;
1432 #else
1433                                         int jump = chan->insmpl - chan->outsmpl;
1434                                         if (jump - MONITOR_DELAY >= 0) {
1435                                                 if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
1436                                                         ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
1437                                                 chan->outsmpl += jump;
1438                                         } else
1439                                                 chan->outsmpl += f->samples;
1440 #endif
1441                                 if (ast_writestream(chan->monitor->write_stream, f) < 0)
1442                                                 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
1443                                 }
1444                         } else
1445                                 res = 0;
1446                 }
1447         }
1448         if (f && (f != fr))
1449                 ast_frfree(f);
1450         chan->blocking = 0;
1451         /* Consider a write failure to force a soft hangup */
1452         if (res < 0)
1453                 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1454         else {
1455                 if ((chan->fout & 0x7fffffff) == 0x7fffffff)
1456                         chan->fout &= 0x80000000;
1457                 else
1458                         chan->fout++;
1459                 chan->fout++;
1460         }
1461         ast_mutex_unlock(&chan->lock);
1462         return res;
1463 }
1464
1465 int ast_set_write_format(struct ast_channel *chan, int fmts)
1466 {
1467         int fmt;
1468         int native;
1469         int res;
1470         
1471         native = chan->nativeformats;
1472         fmt = fmts;
1473         
1474         res = ast_translator_best_choice(&native, &fmt);
1475         if (res < 0) {
1476                 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
1477                         ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
1478                 return -1;
1479         }
1480         
1481         /* Now we have a good choice for both.  We'll write using our native format. */
1482         chan->pvt->rawwriteformat = native;
1483         /* User perspective is fmt */
1484         chan->writeformat = fmt;
1485         /* Free any write translation we have right now */
1486         if (chan->pvt->writetrans)
1487                 ast_translator_free_path(chan->pvt->writetrans);
1488         /* Build a translation path from the user write format to the raw writing format */
1489         chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
1490         if (option_debug)
1491                 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
1492         return 0;
1493 }
1494
1495 int ast_set_read_format(struct ast_channel *chan, int fmts)
1496 {
1497         int fmt;
1498         int native;
1499         int res;
1500         
1501         native = chan->nativeformats;
1502         fmt = fmts;
1503         /* Find a translation path from the native read format to one of the user's read formats */
1504         res = ast_translator_best_choice(&fmt, &native);
1505         if (res < 0) {
1506                 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
1507                         ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
1508                 return -1;
1509         }
1510         
1511         /* Now we have a good choice for both.  We'll write using our native format. */
1512         chan->pvt->rawreadformat = native;
1513         /* User perspective is fmt */
1514         chan->readformat = fmt;
1515         /* Free any read translation we have right now */
1516         if (chan->pvt->readtrans)
1517                 ast_translator_free_path(chan->pvt->readtrans);
1518         /* Build a translation path from the raw read format to the user reading format */
1519         chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
1520         if (option_debug)
1521                 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 
1522                         chan->name, ast_getformatname(chan->readformat));
1523         return 0;
1524 }
1525
1526 struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh)
1527 {
1528         int state = 0;
1529         struct ast_channel *chan;
1530         struct ast_frame *f;
1531         int res = 0;
1532         chan = ast_request(type, format, data);
1533         if (chan) {
1534                 if (oh) {
1535                         char *tmp, *var;
1536                         /* JDG chanvar */
1537                         tmp = oh->variable;
1538                         /* FIXME replace this call with strsep  NOT*/
1539                         while( (var = strtok_r(NULL, "|", &tmp)) ) {
1540                                 pbx_builtin_setvar( chan, var );
1541                         } /* /JDG */
1542                         if (oh->callerid && *oh->callerid)
1543                                 ast_set_callerid(chan, oh->callerid, 1);
1544                         if (oh->account && *oh->account)
1545                                 ast_cdr_setaccount(chan, oh->account);
1546                 }
1547                 if (callerid && strlen(callerid))
1548                         ast_set_callerid(chan, callerid, 1);
1549
1550                 if (!ast_call(chan, data, 0)) {
1551                         while(timeout && (chan->_state != AST_STATE_UP)) {
1552                                 res = ast_waitfor(chan, timeout);
1553                                 if (res < 0) {
1554                                         /* Something not cool, or timed out */
1555                                         break;
1556                                 }
1557                                 /* If done, break out */
1558                                 if (!res)
1559                                         break;
1560                                 if (timeout > -1)
1561                                         timeout = res;
1562                                 f = ast_read(chan);
1563                                 if (!f) {
1564                                         state = AST_CONTROL_HANGUP;
1565                                         res = 0;
1566                                         break;
1567                                 }
1568                                 if (f->frametype == AST_FRAME_CONTROL) {
1569                                         if (f->subclass == AST_CONTROL_RINGING)
1570                                                 state = AST_CONTROL_RINGING;
1571                                         else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
1572                                                 state = f->subclass;
1573                                                 ast_frfree(f);
1574                                                 break;
1575                                         } else if (f->subclass == AST_CONTROL_ANSWER) {
1576                                                 state = f->subclass;
1577                                                 ast_frfree(f);
1578                                                 break;
1579                                         } else if (f->subclass == -1) {
1580                                                 /* Ignore -- just stopping indications */
1581                                         } else {
1582                                                 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
1583                                         }
1584                                 }
1585                                 ast_frfree(f);
1586                         }
1587                 } else
1588                         ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1589         } else
1590                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1591         if (chan) {
1592                 /* Final fixups */
1593                 if (oh) {
1594                         if (oh->context && *oh->context)
1595                                 strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
1596                         if (oh->exten && *oh->exten)
1597                                 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
1598                         chan->priority = oh->priority;
1599                 }
1600                 if (chan->_state == AST_STATE_UP) 
1601                         state = AST_CONTROL_ANSWER;
1602         }
1603         if (outstate)
1604                 *outstate = state;
1605         if (chan && res <= 0) {
1606                 if (!chan->cdr) {
1607                         chan->cdr = ast_cdr_alloc();
1608                         if (chan->cdr)
1609                                 ast_cdr_init(chan->cdr, chan);
1610                 }
1611                 if (chan->cdr) {
1612                         char tmp[256];
1613                         sprintf(tmp, "%s/%s",type,(char *)data);
1614                         ast_cdr_setapp(chan->cdr,"Dial",tmp);
1615                         ast_cdr_update(chan);
1616                         ast_cdr_start(chan->cdr);
1617                         ast_cdr_end(chan->cdr);
1618                         /* If the cause wasn't handled properly */
1619                         if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
1620                                 ast_cdr_failed(chan->cdr);
1621                 } else 
1622                         ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1623                 ast_hangup(chan);
1624                 chan = NULL;
1625         }
1626         return chan;
1627 }
1628
1629 struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid)
1630 {
1631         return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
1632 }
1633
1634 struct ast_channel *ast_request(char *type, int format, void *data)
1635 {
1636         struct chanlist *chan;
1637         struct ast_channel *c = NULL;
1638         int capabilities;
1639         int fmt;
1640         int res;
1641         if (ast_mutex_lock(&chlock)) {
1642                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
1643                 return NULL;
1644         }
1645         chan = backends;
1646         while(chan) {
1647                 if (!strcasecmp(type, chan->type)) {
1648                         capabilities = chan->capabilities;
1649                         fmt = format;
1650                         res = ast_translator_best_choice(&fmt, &capabilities);
1651                         if (res < 0) {
1652                                 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
1653                                 ast_mutex_unlock(&chlock);
1654                                 return NULL;
1655                         }
1656                         ast_mutex_unlock(&chlock);
1657                         if (chan->requester)
1658                                 c = chan->requester(type, capabilities, data);
1659                         if (c) {
1660                                 if (c->_state == AST_STATE_DOWN) {
1661                                         manager_event(EVENT_FLAG_CALL, "Newchannel",
1662                                         "Channel: %s\r\n"
1663                                         "State: %s\r\n"
1664                                         "Callerid: %s\r\n"
1665                                         "Uniqueid: %s\r\n",
1666                                         c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
1667                                 }
1668                         }
1669                         return c;
1670                 }
1671                 chan = chan->next;
1672         }
1673         if (!chan)
1674                 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
1675         ast_mutex_unlock(&chlock);
1676         return c;
1677 }
1678
1679 int ast_parse_device_state(char *device)
1680 {
1681         char name[AST_CHANNEL_NAME] = "";
1682         char *cut;
1683         struct ast_channel *chan;
1684
1685         chan = ast_channel_walk(NULL);
1686         while (chan) {
1687                 strncpy(name, chan->name, sizeof(name)-1);
1688                 cut = strchr(name,'-');
1689                 if (cut)
1690                         *cut = 0;
1691                 if (!strcmp(name, device))
1692                         return AST_DEVICE_INUSE;
1693                 chan = ast_channel_walk(chan);
1694         }
1695         return AST_DEVICE_UNKNOWN;
1696 }
1697
1698 int ast_device_state(char *device)
1699 {
1700         char tech[AST_MAX_EXTENSION] = "";
1701         char *number;
1702         struct chanlist *chanls;
1703         int res = 0;
1704         
1705         strncpy(tech, device, sizeof(tech)-1);
1706         number = strchr(tech, '/');
1707         if (!number) {
1708             return AST_DEVICE_INVALID;
1709         }
1710         *number = 0;
1711         number++;
1712                 
1713         if (ast_mutex_lock(&chlock)) {
1714                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
1715                 return -1;
1716         }
1717         chanls = backends;
1718         while(chanls) {
1719                 if (!strcasecmp(tech, chanls->type)) {
1720                         ast_mutex_unlock(&chlock);
1721                         if (!chanls->devicestate) 
1722                                 return ast_parse_device_state(device);
1723                         else {
1724                                 res = chanls->devicestate(number);
1725                                 if (res == AST_DEVICE_UNKNOWN)
1726                                         return ast_parse_device_state(device);
1727                                 else
1728                                         return res;
1729                         }
1730                 }
1731                 chanls = chanls->next;
1732         }
1733         ast_mutex_unlock(&chlock);
1734         return AST_DEVICE_INVALID;
1735 }
1736
1737 int ast_call(struct ast_channel *chan, char *addr, int timeout) 
1738 {
1739         /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
1740            If the remote end does not answer within the timeout, then do NOT hang up, but 
1741            return anyway.  */
1742         int res = -1;
1743         /* Stop if we're a zombie or need a soft hangup */
1744         ast_mutex_lock(&chan->lock);
1745         if (!chan->zombie && !ast_check_hangup(chan)) 
1746                 if (chan->pvt->call)
1747                         res = chan->pvt->call(chan, addr, timeout);
1748         ast_mutex_unlock(&chan->lock);
1749         return res;
1750 }
1751
1752 int ast_transfer(struct ast_channel *chan, char *dest) 
1753 {
1754         /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
1755            If the remote end does not answer within the timeout, then do NOT hang up, but 
1756            return anyway.  */
1757         int res = -1;
1758         /* Stop if we're a zombie or need a soft hangup */
1759         ast_mutex_lock(&chan->lock);
1760         if (!chan->zombie && !ast_check_hangup(chan)) {
1761                 if (chan->pvt->transfer) {
1762                         res = chan->pvt->transfer(chan, dest);
1763                         if (!res)
1764                                 res = 1;
1765                 } else
1766                         res = 0;
1767         }
1768         ast_mutex_unlock(&chan->lock);
1769         return res;
1770 }
1771
1772 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
1773 {
1774         int pos=0;
1775         int to = ftimeout;
1776         char d;
1777         /* XXX Merge with full version? XXX */
1778         /* Stop if we're a zombie or need a soft hangup */
1779         if (c->zombie || ast_check_hangup(c)) 
1780                 return -1;
1781         if (!len)
1782                 return -1;
1783         do {
1784                 if (c->stream) {
1785                         d = ast_waitstream(c, AST_DIGIT_ANY);
1786                         ast_stopstream(c);
1787                         usleep(1000);
1788                         if (!d)
1789                                 d = ast_waitfordigit(c, to);
1790                 } else {
1791                         d = ast_waitfordigit(c, to);
1792                 }
1793                 if (d < 0)
1794                         return -1;
1795                 if (d == 0) {
1796                         s[pos]='\0';
1797                         return 1;
1798                 }
1799                 if (!strchr(enders, d))
1800                         s[pos++] = d;
1801                 if (strchr(enders, d) || (pos >= len)) {
1802                         s[pos]='\0';
1803                         return 0;
1804                 }
1805                 to = timeout;
1806         } while(1);
1807         /* Never reached */
1808         return 0;
1809 }
1810
1811 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
1812 {
1813         int pos=0;
1814         int to = ftimeout;
1815         char d;
1816         /* Stop if we're a zombie or need a soft hangup */
1817         if (c->zombie || ast_check_hangup(c)) 
1818                 return -1;
1819         if (!len)
1820                 return -1;
1821         do {
1822                 if (c->stream) {
1823                         d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
1824                         ast_stopstream(c);
1825                         usleep(1000);
1826                         if (!d)
1827                                 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
1828                 } else {
1829                         d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
1830                 }
1831                 if (d < 0)
1832                         return -1;
1833                 if (d == 0) {
1834                         s[pos]='\0';
1835                         return 1;
1836                 }
1837                 if (d == 1) {
1838                         s[pos]='\0';
1839                         return 2;
1840                 }
1841                 if (!strchr(enders, d))
1842                         s[pos++] = d;
1843                 if (strchr(enders, d) || (pos >= len)) {
1844                         s[pos]='\0';
1845                         return 0;
1846                 }
1847                 to = timeout;
1848         } while(1);
1849         /* Never reached */
1850         return 0;
1851 }
1852
1853 int ast_channel_supports_html(struct ast_channel *chan)
1854 {
1855         if (chan->pvt->send_html)
1856                 return 1;
1857         return 0;
1858 }
1859
1860 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, char *data, int datalen)
1861 {
1862         if (chan->pvt->send_html)
1863                 return chan->pvt->send_html(chan, subclass, data, datalen);
1864         return -1;
1865 }
1866
1867 int ast_channel_sendurl(struct ast_channel *chan, char *url)
1868 {
1869         if (chan->pvt->send_html)
1870                 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
1871         return -1;
1872 }
1873
1874 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
1875 {
1876         int peerf;
1877         int chanf;
1878         int res;
1879         peerf = peer->nativeformats;
1880         chanf = chan->nativeformats;
1881         res = ast_translator_best_choice(&peerf, &chanf);
1882         if (res < 0) {
1883                 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
1884                 return -1;
1885         }
1886         /* Set read format on channel */
1887         res = ast_set_read_format(chan, peerf);
1888         if (res < 0) {
1889                 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
1890                 return -1;
1891         }
1892         /* Set write format on peer channel */
1893         res = ast_set_write_format(peer, peerf);
1894         if (res < 0) {
1895                 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
1896                 return -1;
1897         }
1898         /* Now we go the other way */
1899         peerf = peer->nativeformats;
1900         chanf = chan->nativeformats;
1901         res = ast_translator_best_choice(&chanf, &peerf);
1902         if (res < 0) {
1903                 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
1904                 return -1;
1905         }
1906         /* Set writeformat on channel */
1907         res = ast_set_write_format(chan, chanf);
1908         if (res < 0) {
1909                 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
1910                 return -1;
1911         }
1912         /* Set read format on peer channel */
1913         res = ast_set_read_format(peer, chanf);
1914         if (res < 0) {
1915                 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
1916                 return -1;
1917         }
1918         return 0;
1919 }
1920
1921 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
1922 {
1923         struct ast_frame null = { AST_FRAME_NULL, };
1924         ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
1925                 clone->name, original->name);
1926         if (original->masq) {
1927                 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
1928                         original->masq->name, original->name);
1929                 return -1;
1930         }
1931         if (clone->masqr) {
1932                 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
1933                         clone->name, clone->masqr->name);
1934                 return -1;
1935         }
1936         original->masq = clone;
1937         clone->masqr = original;
1938         /* XXX can't really hold the lock here, but at the same time, it' s
1939            not really safe not to XXX */
1940         ast_queue_frame(original, &null, 0);
1941         ast_queue_frame(clone, &null, 0);
1942         ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
1943         return 0;
1944 }
1945
1946 void ast_change_name(struct ast_channel *chan, char *newname)
1947 {
1948         char tmp[256];
1949         strncpy(tmp, chan->name, 256);
1950         strncpy(chan->name, newname, sizeof(chan->name) - 1);
1951         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
1952 }
1953
1954 int ast_do_masquerade(struct ast_channel *original, int needlock)
1955 {
1956         int x,i;
1957         int res=0;
1958         char *tmp;
1959         struct ast_var_t *varptr;
1960         struct ast_frame *cur, *prev;
1961         struct ast_channel_pvt *p;
1962         struct ast_channel *clone = original->masq;
1963         int rformat = original->readformat;
1964         int wformat = original->writeformat;
1965         char newn[100];
1966         char orig[100];
1967         char masqn[100];
1968         char zombn[100];
1969         
1970 #if 1
1971         ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
1972                 clone->name, clone->_state, original->name, original->_state);
1973 #endif
1974         /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
1975            the clone channel into the original channel.  Start by killing off the original
1976            channel's backend.   I'm not sure we're going to keep this function, because 
1977            while the features are nice, the cost is very high in terms of pure nastiness. XXX */
1978
1979         if (needlock)
1980                 /* We need the clone's lock, too */
1981                 ast_mutex_lock(&clone->lock);
1982
1983         ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock);
1984
1985         /* Having remembered the original read/write formats, we turn off any translation on either
1986            one */
1987         free_translation(clone);
1988         free_translation(original);
1989
1990
1991         /* Unlink the masquerade */
1992         original->masq = NULL;
1993         clone->masqr = NULL;
1994         
1995         /* Save the original name */
1996         strncpy(orig, original->name, sizeof(orig) - 1);
1997         /* Save the new name */
1998         strncpy(newn, clone->name, sizeof(newn) - 1);
1999         /* Create the masq name */
2000         snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
2001                 
2002         /* Copy the name from the clone channel */
2003         strncpy(original->name, newn, sizeof(original->name)-1);
2004
2005         /* Mangle the name of the clone channel */
2006         strncpy(clone->name, masqn, sizeof(clone->name) - 1);
2007         
2008         /* Notify any managers of the change, first the masq then the other */
2009         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", newn, masqn);
2010         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", orig, newn);
2011
2012         /* Swap the guts */     
2013         p = original->pvt;
2014         original->pvt = clone->pvt;
2015         clone->pvt = p;
2016
2017         /* Save any pending frames on both sides.  Start by counting
2018          * how many we're going to need... */
2019         prev = NULL;
2020         cur = clone->pvt->readq;
2021         x = 0;
2022         while(cur) {
2023                 x++;
2024                 prev = cur;
2025                 cur = cur->next;
2026         }
2027         /* If we had any, prepend them to the ones already in the queue, and 
2028          * load up the alertpipe */
2029         if (prev) {
2030                 prev->next = original->pvt->readq;
2031                 original->pvt->readq = clone->pvt->readq;
2032                 clone->pvt->readq = NULL;
2033                 if (original->pvt->alertpipe[1] > -1) {
2034                         for (i=0;i<x;i++)
2035                                 write(original->pvt->alertpipe[1], &x, sizeof(x));
2036                 }
2037         }
2038         clone->_softhangup = AST_SOFTHANGUP_DEV;
2039
2040
2041         if (clone->pvt->fixup){
2042                 res = clone->pvt->fixup(original, clone, needlock);
2043                 if (res) 
2044                         ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
2045         }
2046
2047         /* Start by disconnecting the original's physical side */
2048         if (clone->pvt->hangup)
2049                 res = clone->pvt->hangup(clone);
2050         if (res) {
2051                 ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
2052                 if (needlock)
2053                         ast_mutex_unlock(&clone->lock);
2054                 return -1;
2055         }
2056         
2057         snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
2058         /* Mangle the name of the clone channel */
2059         strncpy(clone->name, zombn, sizeof(clone->name) - 1);
2060         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", masqn, zombn);
2061
2062         /* Keep the same language.  */
2063         /* Update the type. */
2064         original->type = clone->type;
2065         /* Copy the FD's */
2066         for (x=0;x<AST_MAX_FDS;x++) {
2067                 original->fds[x] = clone->fds[x];
2068         }
2069         /* Append variables from clone channel into original channel */
2070         /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
2071         varptr = original->varshead.first;
2072         if (varptr) {
2073                 while(varptr->entries.next) {
2074                         varptr = varptr->entries.next;
2075                 }
2076                 varptr->entries.next = clone->varshead.first;
2077         } else {
2078                 original->varshead.first = clone->varshead.first;
2079         }
2080         clone->varshead.first = NULL;
2081         /* Presense of ADSI capable CPE follows clone */
2082         original->adsicpe = clone->adsicpe;
2083         /* Bridge remains the same */
2084         /* CDR fields remain the same */
2085         /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
2086         /* Application and data remain the same */
2087         /* Clone exception  becomes real one, as with fdno */
2088         original->exception = clone->exception;
2089         original->fdno = clone->fdno;
2090         /* Schedule context remains the same */
2091         /* Stream stuff stays the same */
2092         /* Keep the original state.  The fixup code will need to work with it most likely */
2093
2094         /* dnid and callerid change to become the new, HOWEVER, we also link the original's
2095            fields back into the defunct 'clone' so that they will be freed when
2096            ast_frfree is eventually called */
2097         tmp = original->dnid;
2098         original->dnid = clone->dnid;
2099         clone->dnid = tmp;
2100         
2101         tmp = original->callerid;
2102         original->callerid = clone->callerid;
2103         clone->callerid = tmp;
2104         
2105         /* Restore original timing file descriptor */
2106         original->fds[AST_MAX_FDS - 2] = original->timingfd;
2107         
2108         /* Our native formats are different now */
2109         original->nativeformats = clone->nativeformats;
2110
2111         /* And of course, so does our current state.  Note we need not
2112            call ast_setstate since the event manager doesn't really consider
2113            these separate */
2114         original->_state = clone->_state;
2115         
2116         /* Context, extension, priority, app data, jump table,  remain the same */
2117         /* pvt switches.  pbx stays the same, as does next */
2118         
2119         /* Set the write format */
2120         ast_set_write_format(original, wformat);
2121
2122         /* Set the read format */
2123         ast_set_read_format(original, rformat);
2124
2125         ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
2126
2127         /* Okay.  Last thing is to let the channel driver know about all this mess, so he
2128            can fix up everything as best as possible */
2129         if (original->pvt->fixup) {
2130                 res = original->pvt->fixup(clone, original, needlock);
2131                 if (res) {
2132                         ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
2133                                 original->type, original->name);
2134                         return -1;
2135                 }
2136         } else
2137                 ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
2138                         original->type, original->name);
2139         
2140         /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
2141            a zombie so nothing tries to touch it.  If it's already been marked as a
2142            zombie, then free it now (since it already is considered invalid). */
2143         if (clone->zombie) {
2144                 ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
2145                 if (needlock)
2146                         ast_mutex_unlock(&clone->lock);
2147                 ast_channel_free(clone);
2148                 manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
2149         } else {
2150                 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
2151                 clone->zombie=1;
2152                 if (needlock)
2153                         ast_mutex_unlock(&clone->lock);
2154         }
2155         
2156         /* Signal any blocker */
2157         if (original->blocking)
2158                 pthread_kill(original->blocker, SIGURG);
2159         ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n",
2160                 original->name, original->_state);
2161         return 0;
2162 }
2163
2164 void ast_set_callerid(struct ast_channel *chan, char *callerid, int anitoo)
2165 {
2166         if (chan->callerid)
2167                 free(chan->callerid);
2168         if (anitoo && chan->ani)
2169                 free(chan->ani);
2170         if (callerid) {
2171                 chan->callerid = strdup(callerid);
2172                 if (anitoo)
2173                         chan->ani = strdup(callerid);
2174         } else {
2175                 chan->callerid = NULL;
2176                 if (anitoo)
2177                         chan->ani = NULL;
2178         }
2179         if (chan->cdr)
2180                 ast_cdr_setcid(chan->cdr, chan);
2181         manager_event(EVENT_FLAG_CALL, "Newcallerid", 
2182                                 "Channel: %s\r\n"
2183                                 "Callerid: %s\r\n"
2184                                 "Uniqueid: %s\r\n",
2185                                 chan->name, chan->callerid ? 
2186                                 chan->callerid : "<Unknown>",
2187                                 chan->uniqueid);
2188 }
2189
2190 int ast_setstate(struct ast_channel *chan, int state)
2191 {
2192         if (chan->_state != state) {
2193                 int oldstate = chan->_state;
2194                 chan->_state = state;
2195                 if (oldstate == AST_STATE_DOWN) {
2196                         ast_device_state_changed(chan->name);
2197                         manager_event(EVENT_FLAG_CALL, "Newchannel",
2198                         "Channel: %s\r\n"
2199                         "State: %s\r\n"
2200                         "Callerid: %s\r\n"
2201                         "Uniqueid: %s\r\n",
2202                         chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
2203                 } else {
2204                         manager_event(EVENT_FLAG_CALL, "Newstate", 
2205                                 "Channel: %s\r\n"
2206                                 "State: %s\r\n"
2207                                 "Callerid: %s\r\n"
2208                                 "Uniqueid: %s\r\n",
2209                                 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
2210                 }
2211         }
2212         return 0;
2213 }
2214
2215 int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
2216 {
2217         /* Copy voice back and forth between the two channels.  Give the peer
2218            the ability to transfer calls with '#<extension' syntax. */
2219         struct ast_channel *cs[3];
2220         int to = -1;
2221         struct ast_frame *f;
2222         struct ast_channel *who = NULL;
2223         int res;
2224         int nativefailed=0;
2225
2226         /* Stop if we're a zombie or need a soft hangup */
2227         if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 
2228                 return -1;
2229         if (c0->bridge) {
2230                 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
2231                         c0->name, c0->bridge->name);
2232                 return -1;
2233         }
2234         if (c1->bridge) {
2235                 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
2236                         c1->name, c1->bridge->name);
2237                 return -1;
2238         }
2239         
2240         /* Keep track of bridge */
2241         c0->bridge = c1;
2242         c1->bridge = c0;
2243         cs[0] = c0;
2244         cs[1] = c1;
2245         
2246         manager_event(EVENT_FLAG_CALL, "Link", 
2247                         "Channel1: %s\r\n"
2248                         "Channel2: %s\r\n",
2249                         c0->name, c1->name);
2250
2251         for (/* ever */;;) {
2252                 /* Stop if we're a zombie or need a soft hangup */
2253                 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
2254                         *fo = NULL;
2255                         if (who) *rc = who;
2256                         res = 0;
2257                         ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",c0->name,c1->name,c0->zombie?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",c1->zombie?"Yes":"No",ast_check_hangup(c1)?"Yes":"No");
2258                         break;
2259                 }
2260                 if (c0->pvt->bridge && 
2261                         (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
2262                                 /* Looks like they share a bridge code */
2263                         if (option_verbose > 2) 
2264                                 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
2265                         if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
2266                                 c0->bridge = NULL;
2267                                 c1->bridge = NULL;
2268                                 manager_event(EVENT_FLAG_CALL, "Unlink", 
2269                                         "Channel1: %s\r\n"
2270                                         "Channel2: %s\r\n",
2271                                         c0->name, c1->name);
2272                                 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
2273                                 return 0;
2274                         }
2275                         /* If they return non-zero then continue on normally.  Let "-2" mean don't worry about
2276                            my not wanting to bridge */
2277                         if ((res != -2) && (res != -3))
2278                                 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
2279                         if (res != -3) nativefailed++;
2280                 }
2281         
2282                         
2283                 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
2284                         !(c0->generator || c1->generator))  {
2285                         if (ast_channel_make_compatible(c0, c1)) {
2286                                 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
2287                                 manager_event(EVENT_FLAG_CALL, "Unlink", 
2288                                         "Channel1: %s\r\n"
2289                                         "Channel2: %s\r\n",
2290                                         c0->name, c1->name);
2291                                 return -1;
2292                         }
2293                 }
2294                 who = ast_waitfor_n(cs, 2, &to);
2295                 if (!who) {
2296                         ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
2297                         continue;
2298                 }
2299                 f = ast_read(who);
2300                 if (!f) {
2301                         *fo = NULL;
2302                         *rc = who;
2303                         res = 0;
2304                         ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
2305                         break;
2306                 }
2307
2308                 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
2309                         *fo = f;
2310                         *rc = who;
2311                         res =  0;
2312                         ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
2313                         break;
2314                 }
2315                 if ((f->frametype == AST_FRAME_VOICE) ||
2316                         (f->frametype == AST_FRAME_TEXT) ||
2317                         (f->frametype == AST_FRAME_VIDEO) || 
2318                         (f->frametype == AST_FRAME_IMAGE) ||
2319                         (f->frametype == AST_FRAME_DTMF)) {
2320                         if ((f->frametype == AST_FRAME_DTMF) && 
2321                                 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
2322                                 if ((who == c0)) {
2323                                         if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
2324                                                 *rc = c0;
2325                                                 *fo = f;
2326                                                 /* Take out of conference mode */
2327                                                 res = 0;
2328                                                 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
2329                                                 break;
2330                                         } else 
2331                                                 goto tackygoto;
2332                                 } else
2333                                 if ((who == c1)) {
2334                                         if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
2335                                                 *rc = c1;
2336                                                 *fo = f;
2337                                                 res =  0;
2338                                                 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
2339                                                 break;
2340                                         } else
2341                                                 goto tackygoto;
2342                                 }
2343                         } else {
2344 #if 0
2345                                 ast_log(LOG_DEBUG, "Read from %s\n", who->name);
2346                                 if (who == last) 
2347                                         ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
2348                                 last = who;
2349 #endif
2350 tackygoto:
2351                                 /* Don't copy packets if there is a generator on either one, since they're
2352                                    not supposed to be listening anyway */
2353                                 if (who == c0) 
2354                                         ast_write(c1, f);
2355                                 else 
2356                                         ast_write(c0, f);
2357                         }
2358                         ast_frfree(f);
2359                 } else
2360                         ast_frfree(f);
2361                 /* Swap who gets priority */
2362                 cs[2] = cs[0];
2363                 cs[0] = cs[1];
2364                 cs[1] = cs[2];
2365         }
2366         c0->bridge = NULL;
2367         c1->bridge = NULL;
2368         manager_event(EVENT_FLAG_CALL, "Unlink", 
2369                                         "Channel1: %s\r\n"
2370                                         "Channel2: %s\r\n",
2371                                         c0->name, c1->name);
2372         ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
2373         return res;
2374 }
2375
2376 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
2377 {
2378         int res;
2379         if (chan->pvt->setoption) {
2380                 res = chan->pvt->setoption(chan, option, data, datalen);
2381                 if (res < 0)
2382                         return res;
2383         } else {
2384                 errno = ENOSYS;
2385                 return -1;
2386         }
2387         if (block) {
2388                 /* XXX Implement blocking -- just wait for our option frame reply, discarding
2389                    intermediate packets. XXX */
2390                 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
2391                 return -1;
2392         }
2393         return 0;
2394 }
2395
2396 struct tonepair_def {
2397         int freq1;
2398         int freq2;
2399         int duration;
2400         int vol;
2401 };
2402
2403 struct tonepair_state {
2404         float freq1;
2405         float freq2;
2406         float vol;
2407         int duration;
2408         int pos;
2409         int origwfmt;
2410         struct ast_frame f;
2411         unsigned char offset[AST_FRIENDLY_OFFSET];
2412         short data[4000];
2413 };
2414
2415 static void tonepair_release(struct ast_channel *chan, void *params)
2416 {
2417         struct tonepair_state *ts = params;
2418         if (chan) {
2419                 ast_set_write_format(chan, ts->origwfmt);
2420         }
2421         free(ts);
2422 }
2423
2424 static void * tonepair_alloc(struct ast_channel *chan, void *params)
2425 {
2426         struct tonepair_state *ts;
2427         struct tonepair_def *td = params;
2428         ts = malloc(sizeof(struct tonepair_state));
2429         if (!ts)
2430                 return NULL;
2431         memset(ts, 0, sizeof(struct tonepair_state));
2432         ts->origwfmt = chan->writeformat;
2433         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
2434                 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
2435                 tonepair_release(NULL, ts);
2436                 ts = NULL;
2437         } else {
2438                 ts->freq1 = td->freq1;
2439                 ts->freq2 = td->freq2;
2440                 ts->duration = td->duration;
2441                 ts->vol = td->vol;
2442         }
2443         /* Let interrupts interrupt :) */
2444         chan->writeinterrupt = 1;
2445         return ts;
2446 }
2447
2448 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
2449 {
2450         struct tonepair_state *ts = data;
2451         int x;
2452
2453         /* we need to prepare a frame with 16 * timelen samples as we're 
2454          * generating SLIN audio
2455          */
2456         len = samples * 2;
2457
2458         if (len > sizeof(ts->data) / 2 - 1) {
2459                 ast_log(LOG_WARNING, "Can't generate that much data!\n");
2460                 return -1;
2461         }
2462         memset(&ts->f, 0, sizeof(ts->f));
2463         for (x=0;x<len/2;x++) {
2464                 ts->data[x] = ts->vol * (
2465                                 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
2466                                 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
2467                         );
2468         }
2469         ts->f.frametype = AST_FRAME_VOICE;
2470         ts->f.subclass = AST_FORMAT_SLINEAR;
2471         ts->f.datalen = len;
2472         ts->f.samples = samples;
2473         ts->f.offset = AST_FRIENDLY_OFFSET;
2474         ts->f.data = ts->data;
2475         ast_write(chan, &ts->f);
2476         ts->pos += x;
2477         if (ts->duration > 0) {
2478                 if (ts->pos >= ts->duration * 8)
2479                         return -1;
2480         }
2481         return 0;
2482 }
2483
2484 static struct ast_generator tonepair = {
2485         alloc: tonepair_alloc,
2486         release: tonepair_release,
2487         generate: tonepair_generator,
2488 };
2489
2490 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
2491 {
2492         struct tonepair_def d = { 0, };
2493         d.freq1 = freq1;
2494         d.freq2 = freq2;
2495         d.duration = duration;
2496         if (vol < 1)
2497                 d.vol = 8192;
2498         else
2499                 d.vol = vol;
2500         if (ast_activate_generator(chan, &tonepair, &d))
2501                 return -1;
2502         return 0;
2503 }
2504
2505 void ast_tonepair_stop(struct ast_channel *chan)
2506 {
2507         ast_deactivate_generator(chan);
2508 }
2509
2510 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
2511 {
2512         struct ast_frame *f;
2513         int res;
2514         if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
2515                 return res;
2516
2517         /* Give us some wiggle room */
2518         while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
2519                 f = ast_read(chan);
2520                 if (f)
2521                         ast_frfree(f);
2522                 else
2523                         return -1;
2524         }
2525         return 0;
2526 }
2527
2528 unsigned int ast_get_group(char *s)
2529 {
2530         char *copy;
2531         char *piece;
2532         char *c=NULL;
2533         int start=0, finish=0,x;
2534         unsigned int group = 0;
2535         copy = ast_strdupa(s);
2536         if (!copy) {
2537                 ast_log(LOG_ERROR, "Out of memory\n");
2538                 return 0;
2539         }
2540         c = copy;
2541         
2542         while((piece = strsep(&c, ","))) {
2543                 if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
2544                         /* Range */
2545                 } else if (sscanf(piece, "%d", &start)) {
2546                         /* Just one */
2547                         finish = start;
2548                 } else {
2549                         ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.  Using '0'\n", s,piece);
2550                         return 0;
2551                 }
2552                 for (x=start;x<=finish;x++) {
2553                         if ((x > 31) || (x < 0)) {
2554                                 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x);
2555                         } else
2556                                 group |= (1 << x);
2557                 }
2558         }
2559         return group;
2560 }