Consider whentohangup in timeout (bug #1107)
[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;
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         time(&now);
821         /* Perform any pending masquerades */
822         for (x=0;x<n;x++) {
823                 ast_mutex_lock(&c[x]->lock);
824                 if (c[x]->whentohangup) {
825                         diff = c[x]->whentohangup - now;
826                         if (!havewhen || (diff < whentohangup)) {
827                                 havewhen++;
828                                 whentohangup = diff;
829                         }
830                 }
831                 if (c[x]->masq) {
832                         if (ast_do_masquerade(c[x], 1)) {
833                                 ast_log(LOG_WARNING, "Masquerade failed\n");
834                                 *ms = -1;
835                                 ast_mutex_unlock(&c[x]->lock);
836                                 return NULL;
837                         }
838                 }
839                 ast_mutex_unlock(&c[x]->lock);
840         }
841         
842         tv.tv_sec = *ms / 1000;
843         tv.tv_usec = (*ms % 1000) * 1000;
844         
845         if (havewhen) {
846                 if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
847                         tv.tv_sec = whentohangup / 1000;
848                         tv.tv_usec = (whentohangup % 1000) * 1000;
849                 }
850         }
851         FD_ZERO(&rfds);
852         FD_ZERO(&efds);
853
854         for (x=0;x<n;x++) {
855                 for (y=0;y<AST_MAX_FDS;y++) {
856                         if (c[x]->fds[y] > -1) {
857                                 FD_SET(c[x]->fds[y], &rfds);
858                                 FD_SET(c[x]->fds[y], &efds);
859                                 if (c[x]->fds[y] > max)
860                                         max = c[x]->fds[y];
861                         }
862                 }
863                 CHECK_BLOCKING(c[x]);
864         }
865         for (x=0;x<nfds; x++) {
866                 FD_SET(fds[x], &rfds);
867                 FD_SET(fds[x], &efds);
868                 if (fds[x] > max)
869                         max = fds[x];
870         }
871         if ((*ms >= 0) || (havewhen))
872                 res = ast_select(max + 1, &rfds, NULL, &efds, &tv);
873         else
874                 res = ast_select(max + 1, &rfds, NULL, &efds, NULL);
875
876         if (res < 0) {
877                 for (x=0;x<n;x++) 
878                         c[x]->blocking = 0;
879                 /* Simulate a timeout if we were interrupted */
880                 if (errno != EINTR)
881                         *ms = -1;
882                 else {
883                         /* Just an interrupt */
884 #if 0
885                         *ms = 0;
886 #endif                  
887                 }
888                 return NULL;
889         }
890
891         for (x=0;x<n;x++) {
892                 c[x]->blocking = 0;
893                 for (y=0;y<AST_MAX_FDS;y++) {
894                         if (c[x]->fds[y] > -1) {
895                                 if ((FD_ISSET(c[x]->fds[y], &rfds) || FD_ISSET(c[x]->fds[y], &efds)) && !winner) {
896                                         /* Set exception flag if appropriate */
897                                         if (FD_ISSET(c[x]->fds[y], &efds))
898                                                 c[x]->exception = 1;
899                                         c[x]->fdno = y;
900                                         winner = c[x];
901                                 }
902                         }
903                 }
904         }
905         for (x=0;x<nfds;x++) {
906                 if ((FD_ISSET(fds[x], &rfds) || FD_ISSET(fds[x], &efds)) && !winner) {
907                         if (outfd)
908                                 *outfd = fds[x];
909                         if (FD_ISSET(fds[x], &efds) && exception)
910                                 *exception = 1;
911                         winner = NULL;
912                 }
913         }
914         *ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
915         return winner;
916 }
917
918 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
919 {
920         return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
921 }
922
923 int ast_waitfor(struct ast_channel *c, int ms)
924 {
925         struct ast_channel *chan;
926         int oldms = ms;
927         chan = ast_waitfor_n(&c, 1, &ms);
928         if (ms < 0) {
929                 if (oldms < 0)
930                         return 0;
931                 else
932                         return -1;
933         }
934         return ms;
935 }
936
937 char ast_waitfordigit(struct ast_channel *c, int ms)
938 {
939         /* XXX Should I be merged with waitfordigit_full XXX */
940         struct ast_frame *f;
941         char result = 0;
942         /* Stop if we're a zombie or need a soft hangup */
943         if (c->zombie || ast_check_hangup(c)) 
944                 return -1;
945         /* Wait for a digit, no more than ms milliseconds total. */
946         while(ms && !result) {
947                 ms = ast_waitfor(c, ms);
948                 if (ms < 0) /* Error */
949                         result = -1; 
950                 else if (ms > 0) {
951                         /* Read something */
952                         f = ast_read(c);
953                         if (f) {
954                                 if (f->frametype == AST_FRAME_DTMF) 
955                                         result = f->subclass;
956                                 ast_frfree(f);
957                         } else
958                                 result = -1;
959                 }
960         }
961         return result;
962 }
963
964 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
965 {
966         int res = -1;
967 #ifdef ZAPTEL_OPTIMIZATIONS
968         if (c->timingfd > -1) {
969                 if (!func) {
970                         samples = 0;
971                         data = 0;
972                 }
973                 ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
974                 res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
975                 c->timingfunc = func;
976                 c->timingdata = data;
977         }
978 #endif  
979         return res;
980 }
981 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audio, int ctrl)
982 {
983         struct ast_frame *f;
984         char result = 0;
985         struct ast_channel *rchan;
986         int outfd;
987         /* Stop if we're a zombie or need a soft hangup */
988         if (c->zombie || ast_check_hangup(c)) 
989                 return -1;
990         /* Wait for a digit, no more than ms milliseconds total. */
991         while(ms && !result) {
992                 rchan = ast_waitfor_nandfds(&c, 1, &audio, (audio > -1) ? 1 : 0, NULL, &outfd, &ms);
993                 if ((!rchan) && (outfd < 0) && (ms)) /* Error */
994                         result = -1; 
995                 else if (outfd > -1) {
996                         result = 1;
997                 } else if (rchan) {
998                         /* Read something */
999                         f = ast_read(c);
1000                         if (f) {
1001                                 if (f->frametype == AST_FRAME_DTMF) 
1002                                         result = f->subclass;
1003                                 ast_frfree(f);
1004                         } else
1005                                 result = -1;
1006                 }
1007         }
1008         return result;
1009 }
1010
1011 struct ast_frame *ast_read(struct ast_channel *chan)
1012 {
1013         struct ast_frame *f = NULL;
1014         int blah;
1015 #ifdef ZAPTEL_OPTIMIZATIONS
1016         int (*func)(void *);
1017         void *data;
1018 #endif
1019         static struct ast_frame null_frame = 
1020         {
1021                 AST_FRAME_NULL,
1022         };
1023         
1024         ast_mutex_lock(&chan->lock);
1025         if (chan->masq) {
1026                 if (ast_do_masquerade(chan, 1)) {
1027                         ast_log(LOG_WARNING, "Failed to perform masquerade\n");
1028                         f = NULL;
1029                 } else
1030                         f =  &null_frame;
1031                 ast_mutex_unlock(&chan->lock);
1032                 return f;
1033         }
1034
1035         /* Stop if we're a zombie or need a soft hangup */
1036         if (chan->zombie || ast_check_hangup(chan)) {
1037                 if (chan->generator)
1038                         ast_deactivate_generator(chan);
1039                 ast_mutex_unlock(&chan->lock);
1040                 return NULL;
1041         }
1042
1043         if (!chan->deferdtmf && strlen(chan->dtmfq)) {
1044                 /* We have DTMF that has been deferred.  Return it now */
1045                 chan->dtmff.frametype = AST_FRAME_DTMF;
1046                 chan->dtmff.subclass = chan->dtmfq[0];
1047                 /* Drop first digit */
1048                 memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
1049                 ast_mutex_unlock(&chan->lock);
1050                 return &chan->dtmff;
1051         }
1052         
1053         /* Read and ignore anything on the alertpipe, but read only
1054            one sizeof(blah) per frame that we send from it */
1055         if (chan->pvt->alertpipe[0] > -1) {
1056                 read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
1057         }
1058 #ifdef ZAPTEL_OPTIMIZATIONS
1059         if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
1060                 chan->exception = 0;
1061                 blah = -1;
1062                 ioctl(chan->timingfd, ZT_TIMERACK, &blah);
1063                 func = chan->timingfunc;
1064                 data = chan->timingdata;
1065                 ast_mutex_unlock(&chan->lock);
1066                 if (func) {
1067 #if 0
1068                         ast_log(LOG_DEBUG, "Calling private function\n");
1069 #endif                  
1070                         func(data);
1071                 } else {
1072                         blah = 0;
1073                         ast_mutex_lock(&chan->lock);
1074                         ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
1075                         chan->timingdata = NULL;
1076                         ast_mutex_unlock(&chan->lock);
1077                 }
1078                 f =  &null_frame;
1079                 return f;
1080         }
1081 #endif
1082         /* Check for pending read queue */
1083         if (chan->pvt->readq) {
1084                 f = chan->pvt->readq;
1085                 chan->pvt->readq = f->next;
1086                 /* Interpret hangup and return NULL */
1087                 if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
1088                         ast_frfree(f);
1089                         f = NULL;
1090                 }
1091         } else {
1092                 chan->blocker = pthread_self();
1093                 if (chan->exception) {
1094                         if (chan->pvt->exception) 
1095                                 f = chan->pvt->exception(chan);
1096                         else {
1097                                 ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
1098                                 f = &null_frame;
1099                         }
1100                         /* Clear the exception flag */
1101                         chan->exception = 0;
1102                 } else
1103                 if (chan->pvt->read)
1104                         f = chan->pvt->read(chan);
1105                 else
1106                         ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
1107         }
1108
1109
1110         if (f && (f->frametype == AST_FRAME_VOICE)) {
1111                 if (!(f->subclass & chan->nativeformats)) {
1112                         /* This frame can't be from the current native formats -- drop it on the
1113                            floor */
1114                         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));
1115                         ast_frfree(f);
1116                         f = &null_frame;
1117                 } else {
1118                         if (chan->monitor && chan->monitor->read_stream ) {
1119 #ifndef MONITOR_CONSTANT_DELAY
1120                                 int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
1121                                 if (jump >= 0) {
1122                                         if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
1123                                                 ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
1124                                         chan->insmpl += jump + 2 * f->samples;
1125                                 } else
1126                                         chan->insmpl+= f->samples;
1127 #else
1128                                 int jump = chan->outsmpl - chan->insmpl;
1129                                 if (jump - MONITOR_DELAY >= 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;
1133                                 } else
1134                                         chan->insmpl += f->samples;
1135 #endif
1136                                 if (ast_writestream(chan->monitor->read_stream, f) < 0)
1137                                         ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
1138                         }
1139                         if (chan->pvt->readtrans) {
1140                                 f = ast_translate(chan->pvt->readtrans, f, 1);
1141                                 if (!f)
1142                                         f = &null_frame;
1143                         }
1144                 }
1145         }
1146
1147         /* Make sure we always return NULL in the future */
1148         if (!f) {
1149                 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1150                 if (chan->generator)
1151                         ast_deactivate_generator(chan);
1152                 /* End the CDR if appropriate */
1153                 if (chan->cdr)
1154                         ast_cdr_end(chan->cdr);
1155         } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
1156                 if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
1157                         chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
1158                 else
1159                         ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
1160                 f = &null_frame;
1161         } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
1162                 /* Answer the CDR */
1163                 ast_setstate(chan, AST_STATE_UP);
1164                 ast_cdr_answer(chan->cdr);
1165         } 
1166         ast_mutex_unlock(&chan->lock);
1167
1168         /* Run any generator sitting on the line */
1169         if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
1170                 /* Mask generator data temporarily */
1171                 void *tmp;
1172                 int res;
1173                 tmp = chan->generatordata;
1174                 chan->generatordata = NULL;
1175                 res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
1176                 chan->generatordata = tmp;
1177                 if (res) {
1178                         ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
1179                         ast_deactivate_generator(chan);
1180                 }
1181         }
1182         if (chan->fin & 0x80000000)
1183                 ast_frame_dump(chan->name, f, "<<");
1184         if ((chan->fin & 0x7fffffff) == 0x7fffffff)
1185                 chan->fin &= 0x80000000;
1186         else
1187                 chan->fin++;
1188         return f;
1189 }
1190
1191 int ast_indicate(struct ast_channel *chan, int condition)
1192 {
1193         int res = -1;
1194         /* Stop if we're a zombie or need a soft hangup */
1195         if (chan->zombie || ast_check_hangup(chan)) 
1196                 return -1;
1197         ast_mutex_lock(&chan->lock);
1198         if (chan->pvt->indicate)
1199                 res = chan->pvt->indicate(chan, condition);
1200         ast_mutex_unlock(&chan->lock);
1201         if (!chan->pvt->indicate || res) {
1202                 /*
1203                  * Device does not support (that) indication, lets fake
1204                  * it by doing our own tone generation. (PM2002)
1205                  */
1206                 if (condition >= 0) {
1207                         const struct tone_zone_sound *ts = NULL;
1208                         switch (condition) {
1209                          case AST_CONTROL_RINGING:
1210                                 ts = ast_get_indication_tone(chan->zone, "ring");
1211                                 break;
1212                          case AST_CONTROL_BUSY:
1213                                 ts = ast_get_indication_tone(chan->zone, "busy");
1214                                 break;
1215                          case AST_CONTROL_CONGESTION:
1216                                 ts = ast_get_indication_tone(chan->zone, "congestion");
1217                                 break;
1218                         }
1219                         if (ts && ts->data[0]) {
1220                                 ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
1221                                 ast_playtones_start(chan,0,ts->data, 1);
1222                                 res = 0;
1223                         } else if (condition == AST_CONTROL_PROGRESS) {
1224                                 /* ast_playtones_stop(chan); */
1225                         } else {
1226                                 /* not handled */
1227                                 ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
1228                                 res = -1;
1229                         }
1230                 }
1231                 else ast_playtones_stop(chan);
1232         }
1233         return res;
1234 }
1235
1236 int ast_recvchar(struct ast_channel *chan, int timeout)
1237 {
1238         int res,ourto,c;
1239         struct ast_frame *f;
1240         
1241         ourto = timeout;
1242         for(;;)
1243            {
1244                 if (ast_check_hangup(chan)) return -1;
1245                 res = ast_waitfor(chan,ourto);
1246                 if (res <= 0) /* if timeout */
1247                    {
1248                         return 0;
1249                    }
1250                 ourto = res;
1251                 f = ast_read(chan);
1252                 if (f == NULL) return -1; /* if hangup */
1253                 if ((f->frametype == AST_FRAME_CONTROL) &&
1254                     (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */
1255                 if (f->frametype == AST_FRAME_TEXT)  /* if a text frame */
1256                    {
1257                         c = *((char *)f->data);  /* get the data */
1258                         ast_frfree(f);
1259                         return(c);
1260                    }
1261                 ast_frfree(f);
1262         }
1263 }
1264
1265 int ast_sendtext(struct ast_channel *chan, char *text)
1266 {
1267         int res = 0;
1268         /* Stop if we're a zombie or need a soft hangup */
1269         if (chan->zombie || ast_check_hangup(chan)) 
1270                 return -1;
1271         CHECK_BLOCKING(chan);
1272         if (chan->pvt->send_text)
1273                 res = chan->pvt->send_text(chan, text);
1274         chan->blocking = 0;
1275         return res;
1276 }
1277
1278 static int do_senddigit(struct ast_channel *chan, char digit)
1279 {
1280         int res = -1;
1281
1282         if (chan->pvt->send_digit)
1283                 res = chan->pvt->send_digit(chan, digit);
1284         if (!chan->pvt->send_digit || res) {
1285                 /*
1286                  * Device does not support DTMF tones, lets fake
1287                  * it by doing our own generation. (PM2002)
1288                  */
1289                 static const char* dtmf_tones[] = {
1290                         "!941+1336/100,!0/100", /* 0 */
1291                         "!697+1209/100,!0/100", /* 1 */
1292                         "!697+1336/100,!0/100", /* 2 */
1293                         "!697+1477/100,!0/100", /* 3 */
1294                         "!770+1209/100,!0/100", /* 4 */
1295                         "!770+1336/100,!0/100", /* 5 */
1296                         "!770+1477/100,!0/100", /* 6 */
1297                         "!852+1209/100,!0/100", /* 7 */
1298                         "!852+1336/100,!0/100", /* 8 */
1299                         "!852+1477/100,!0/100", /* 9 */
1300                         "!697+1633/100,!0/100", /* A */
1301                         "!770+1633/100,!0/100", /* B */
1302                         "!852+1633/100,!0/100", /* C */
1303                         "!941+1633/100,!0/100", /* D */
1304                         "!941+1209/100,!0/100", /* * */
1305                         "!941+1477/100,!0/100" };       /* # */
1306                 if (digit >= '0' && digit <='9')
1307                         ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
1308                 else if (digit >= 'A' && digit <= 'D')
1309                         ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
1310                 else if (digit == '*')
1311                         ast_playtones_start(chan,0,dtmf_tones[14], 0);
1312                 else if (digit == '#')
1313                         ast_playtones_start(chan,0,dtmf_tones[15], 0);
1314                 else {
1315                         /* not handled */
1316                         ast_log(LOG_WARNING, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
1317                         return -1;
1318                 }
1319         }
1320         return 0;
1321 }
1322
1323 int ast_prod(struct ast_channel *chan)
1324 {
1325         struct ast_frame a = { AST_FRAME_VOICE };
1326         char nothing[128];
1327         /* Send an empty audio frame to get things moving */
1328         if (chan->_state != AST_STATE_UP) {
1329                 ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
1330                 a.subclass = chan->pvt->rawwriteformat;
1331                 a.data = nothing + AST_FRIENDLY_OFFSET;
1332                 if (ast_write(chan, &a))
1333                         ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
1334         }
1335         return 0;
1336 }
1337
1338 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
1339 {
1340         int res;
1341         if (!chan->pvt->write_video)
1342                 return 0;
1343         res = ast_write(chan, fr);
1344         if (!res)
1345                 res = 1;
1346         return res;
1347 }
1348
1349 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
1350 {
1351         int res = -1;
1352         struct ast_frame *f = NULL;
1353         /* Stop if we're a zombie or need a soft hangup */
1354         ast_mutex_lock(&chan->lock);
1355         if (chan->zombie || ast_check_hangup(chan))  {
1356                 ast_mutex_unlock(&chan->lock);
1357                 return -1;
1358         }
1359         /* Handle any pending masquerades */
1360         if (chan->masq) {
1361                 if (ast_do_masquerade(chan, 1)) {
1362                         ast_log(LOG_WARNING, "Failed to perform masquerade\n");
1363                         ast_mutex_unlock(&chan->lock);
1364                         return -1;
1365                 }
1366         }
1367         if (chan->masqr) {
1368                 ast_mutex_unlock(&chan->lock);
1369                 return 0;
1370         }
1371         if (chan->generatordata) {
1372                 if (chan->writeinterrupt)
1373                         ast_deactivate_generator(chan);
1374                 else {
1375                         ast_mutex_unlock(&chan->lock);
1376                         return 0;
1377                 }
1378         }
1379         if (chan->fout & 0x80000000)
1380                 ast_frame_dump(chan->name, fr, ">>");
1381         CHECK_BLOCKING(chan);
1382         switch(fr->frametype) {
1383         case AST_FRAME_CONTROL:
1384                 /* XXX Interpret control frames XXX */
1385                 ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
1386                 break;
1387         case AST_FRAME_DTMF:
1388                 chan->blocking = 0;
1389                 ast_mutex_unlock(&chan->lock);
1390                 res = do_senddigit(chan,fr->subclass);
1391                 ast_mutex_lock(&chan->lock);
1392                 CHECK_BLOCKING(chan);
1393                 break;
1394         case AST_FRAME_TEXT:
1395                 if (chan->pvt->send_text)
1396                         res = chan->pvt->send_text(chan, (char *) fr->data);
1397                 break;
1398         case AST_FRAME_VIDEO:
1399                 /* XXX Handle translation of video codecs one day XXX */
1400                 if (chan->pvt->write_video)
1401                         res = chan->pvt->write_video(chan, fr);
1402                 else
1403                         res = 0;
1404                 break;
1405         default:
1406                 if (chan->pvt->write) {
1407                         if (chan->pvt->writetrans) {
1408                                 f = ast_translate(chan->pvt->writetrans, fr, 0);
1409                         } else
1410                                 f = fr;
1411                         if (f) {
1412                                 res = chan->pvt->write(chan, f);
1413                                 if( chan->monitor &&
1414                                                 chan->monitor->write_stream &&
1415                                                 f && ( f->frametype == AST_FRAME_VOICE ) ) {
1416 #ifndef MONITOR_CONSTANT_DELAY
1417                                         int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
1418                                         if (jump >= 0) {
1419                                                 if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
1420                                                         ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
1421                                                 chan->outsmpl += jump + 2 * f->samples;
1422                                         } else
1423                                                 chan->outsmpl += f->samples;
1424 #else
1425                                         int jump = chan->insmpl - chan->outsmpl;
1426                                         if (jump - MONITOR_DELAY >= 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;
1430                                         } else
1431                                                 chan->outsmpl += f->samples;
1432 #endif
1433                                 if (ast_writestream(chan->monitor->write_stream, f) < 0)
1434                                                 ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
1435                                 }
1436                         } else
1437                                 res = 0;
1438                 }
1439         }
1440         if (f && (f != fr))
1441                 ast_frfree(f);
1442         chan->blocking = 0;
1443         /* Consider a write failure to force a soft hangup */
1444         if (res < 0)
1445                 chan->_softhangup |= AST_SOFTHANGUP_DEV;
1446         else {
1447                 if ((chan->fout & 0x7fffffff) == 0x7fffffff)
1448                         chan->fout &= 0x80000000;
1449                 else
1450                         chan->fout++;
1451                 chan->fout++;
1452         }
1453         ast_mutex_unlock(&chan->lock);
1454         return res;
1455 }
1456
1457 int ast_set_write_format(struct ast_channel *chan, int fmts)
1458 {
1459         int fmt;
1460         int native;
1461         int res;
1462         
1463         native = chan->nativeformats;
1464         fmt = fmts;
1465         
1466         res = ast_translator_best_choice(&native, &fmt);
1467         if (res < 0) {
1468                 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
1469                         ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
1470                 return -1;
1471         }
1472         
1473         /* Now we have a good choice for both.  We'll write using our native format. */
1474         chan->pvt->rawwriteformat = native;
1475         /* User perspective is fmt */
1476         chan->writeformat = fmt;
1477         /* Free any write translation we have right now */
1478         if (chan->pvt->writetrans)
1479                 ast_translator_free_path(chan->pvt->writetrans);
1480         /* Build a translation path from the user write format to the raw writing format */
1481         chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
1482         if (option_debug)
1483                 ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
1484         return 0;
1485 }
1486
1487 int ast_set_read_format(struct ast_channel *chan, int fmts)
1488 {
1489         int fmt;
1490         int native;
1491         int res;
1492         
1493         native = chan->nativeformats;
1494         fmt = fmts;
1495         /* Find a translation path from the native read format to one of the user's read formats */
1496         res = ast_translator_best_choice(&fmt, &native);
1497         if (res < 0) {
1498                 ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
1499                         ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
1500                 return -1;
1501         }
1502         
1503         /* Now we have a good choice for both.  We'll write using our native format. */
1504         chan->pvt->rawreadformat = native;
1505         /* User perspective is fmt */
1506         chan->readformat = fmt;
1507         /* Free any read translation we have right now */
1508         if (chan->pvt->readtrans)
1509                 ast_translator_free_path(chan->pvt->readtrans);
1510         /* Build a translation path from the raw read format to the user reading format */
1511         chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
1512         if (option_debug)
1513                 ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 
1514                         chan->name, ast_getformatname(chan->readformat));
1515         return 0;
1516 }
1517
1518 struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh)
1519 {
1520         int state = 0;
1521         struct ast_channel *chan;
1522         struct ast_frame *f;
1523         int res = 0;
1524         chan = ast_request(type, format, data);
1525         if (chan) {
1526                 if (oh) {
1527                         char *tmp, *var;
1528                         /* JDG chanvar */
1529                         tmp = oh->variable;
1530                         /* FIXME replace this call with strsep  NOT*/
1531                         while( (var = strtok_r(NULL, "|", &tmp)) ) {
1532                                 pbx_builtin_setvar( chan, var );
1533                         } /* /JDG */
1534                         if (oh->callerid && *oh->callerid)
1535                                 ast_set_callerid(chan, oh->callerid, 1);
1536                         if (oh->account && *oh->account)
1537                                 ast_cdr_setaccount(chan, oh->account);
1538                 }
1539                 if (callerid && strlen(callerid))
1540                         ast_set_callerid(chan, callerid, 1);
1541
1542                 if (!ast_call(chan, data, 0)) {
1543                         while(timeout && (chan->_state != AST_STATE_UP)) {
1544                                 res = ast_waitfor(chan, timeout);
1545                                 if (res < 0) {
1546                                         /* Something not cool, or timed out */
1547                                         break;
1548                                 }
1549                                 /* If done, break out */
1550                                 if (!res)
1551                                         break;
1552                                 if (timeout > -1)
1553                                         timeout = res;
1554                                 f = ast_read(chan);
1555                                 if (!f) {
1556                                         state = AST_CONTROL_HANGUP;
1557                                         res = 0;
1558                                         break;
1559                                 }
1560                                 if (f->frametype == AST_FRAME_CONTROL) {
1561                                         if (f->subclass == AST_CONTROL_RINGING)
1562                                                 state = AST_CONTROL_RINGING;
1563                                         else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
1564                                                 state = f->subclass;
1565                                                 ast_frfree(f);
1566                                                 break;
1567                                         } else if (f->subclass == AST_CONTROL_ANSWER) {
1568                                                 state = f->subclass;
1569                                                 ast_frfree(f);
1570                                                 break;
1571                                         } else {
1572                                                 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
1573                                         }
1574                                 }
1575                                 ast_frfree(f);
1576                         }
1577                 } else
1578                         ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1579         } else
1580                 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
1581         if (chan) {
1582                 /* Final fixups */
1583                 if (oh) {
1584                         if (oh->context && *oh->context)
1585                                 strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
1586                         if (oh->exten && *oh->exten)
1587                                 strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
1588                         chan->priority = oh->priority;
1589                 }
1590                 if (chan->_state == AST_STATE_UP) 
1591                         state = AST_CONTROL_ANSWER;
1592         }
1593         if (outstate)
1594                 *outstate = state;
1595         if (chan && res <= 0) {
1596                 if (!chan->cdr) {
1597                         chan->cdr = ast_cdr_alloc();
1598                         if (chan->cdr)
1599                                 ast_cdr_init(chan->cdr, chan);
1600                 }
1601                 if (chan->cdr) {
1602                         char tmp[256];
1603                         sprintf(tmp, "%s/%s",type,(char *)data);
1604                         ast_cdr_setapp(chan->cdr,"Dial",tmp);
1605                         ast_cdr_update(chan);
1606                         ast_cdr_start(chan->cdr);
1607                         ast_cdr_end(chan->cdr);
1608                         /* If the cause wasn't handled properly */
1609                         if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
1610                                 ast_cdr_failed(chan->cdr);
1611                 } else 
1612                         ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
1613                 ast_hangup(chan);
1614                 chan = NULL;
1615         }
1616         return chan;
1617 }
1618
1619 struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid)
1620 {
1621         return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
1622 }
1623
1624 struct ast_channel *ast_request(char *type, int format, void *data)
1625 {
1626         struct chanlist *chan;
1627         struct ast_channel *c = NULL;
1628         int capabilities;
1629         int fmt;
1630         int res;
1631         if (ast_mutex_lock(&chlock)) {
1632                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
1633                 return NULL;
1634         }
1635         chan = backends;
1636         while(chan) {
1637                 if (!strcasecmp(type, chan->type)) {
1638                         capabilities = chan->capabilities;
1639                         fmt = format;
1640                         res = ast_translator_best_choice(&fmt, &capabilities);
1641                         if (res < 0) {
1642                                 ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
1643                                 ast_mutex_unlock(&chlock);
1644                                 return NULL;
1645                         }
1646                         ast_mutex_unlock(&chlock);
1647                         if (chan->requester)
1648                                 c = chan->requester(type, capabilities, data);
1649                         if (c) {
1650                                 if (c->_state == AST_STATE_DOWN) {
1651                                         manager_event(EVENT_FLAG_CALL, "Newchannel",
1652                                         "Channel: %s\r\n"
1653                                         "State: %s\r\n"
1654                                         "Callerid: %s\r\n"
1655                                         "Uniqueid: %s\r\n",
1656                                         c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
1657                                 }
1658                         }
1659                         return c;
1660                 }
1661                 chan = chan->next;
1662         }
1663         if (!chan)
1664                 ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
1665         ast_mutex_unlock(&chlock);
1666         return c;
1667 }
1668
1669 int ast_parse_device_state(char *device)
1670 {
1671         char name[AST_CHANNEL_NAME] = "";
1672         char *cut;
1673         struct ast_channel *chan;
1674
1675         chan = ast_channel_walk(NULL);
1676         while (chan) {
1677                 strncpy(name, chan->name, sizeof(name)-1);
1678                 cut = strchr(name,'-');
1679                 if (cut)
1680                         *cut = 0;
1681                 if (!strcmp(name, device))
1682                         return AST_DEVICE_INUSE;
1683                 chan = ast_channel_walk(chan);
1684         }
1685         return AST_DEVICE_UNKNOWN;
1686 }
1687
1688 int ast_device_state(char *device)
1689 {
1690         char tech[AST_MAX_EXTENSION] = "";
1691         char *number;
1692         struct chanlist *chanls;
1693         int res = 0;
1694         
1695         strncpy(tech, device, sizeof(tech)-1);
1696         number = strchr(tech, '/');
1697         if (!number) {
1698             return AST_DEVICE_INVALID;
1699         }
1700         *number = 0;
1701         number++;
1702                 
1703         if (ast_mutex_lock(&chlock)) {
1704                 ast_log(LOG_WARNING, "Unable to lock channel list\n");
1705                 return -1;
1706         }
1707         chanls = backends;
1708         while(chanls) {
1709                 if (!strcasecmp(tech, chanls->type)) {
1710                         ast_mutex_unlock(&chlock);
1711                         if (!chanls->devicestate) 
1712                                 return ast_parse_device_state(device);
1713                         else {
1714                                 res = chanls->devicestate(number);
1715                                 if (res == AST_DEVICE_UNKNOWN)
1716                                         return ast_parse_device_state(device);
1717                                 else
1718                                         return res;
1719                         }
1720                 }
1721                 chanls = chanls->next;
1722         }
1723         ast_mutex_unlock(&chlock);
1724         return AST_DEVICE_INVALID;
1725 }
1726
1727 int ast_call(struct ast_channel *chan, char *addr, int timeout) 
1728 {
1729         /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
1730            If the remote end does not answer within the timeout, then do NOT hang up, but 
1731            return anyway.  */
1732         int res = -1;
1733         /* Stop if we're a zombie or need a soft hangup */
1734         ast_mutex_lock(&chan->lock);
1735         if (!chan->zombie && !ast_check_hangup(chan)) 
1736                 if (chan->pvt->call)
1737                         res = chan->pvt->call(chan, addr, timeout);
1738         ast_mutex_unlock(&chan->lock);
1739         return res;
1740 }
1741
1742 int ast_transfer(struct ast_channel *chan, char *dest) 
1743 {
1744         /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
1745            If the remote end does not answer within the timeout, then do NOT hang up, but 
1746            return anyway.  */
1747         int res = -1;
1748         /* Stop if we're a zombie or need a soft hangup */
1749         ast_mutex_lock(&chan->lock);
1750         if (!chan->zombie && !ast_check_hangup(chan)) {
1751                 if (chan->pvt->transfer) {
1752                         res = chan->pvt->transfer(chan, dest);
1753                         if (!res)
1754                                 res = 1;
1755                 } else
1756                         res = 0;
1757         }
1758         ast_mutex_unlock(&chan->lock);
1759         return res;
1760 }
1761
1762 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
1763 {
1764         int pos=0;
1765         int to = ftimeout;
1766         char d;
1767         /* XXX Merge with full version? XXX */
1768         /* Stop if we're a zombie or need a soft hangup */
1769         if (c->zombie || ast_check_hangup(c)) 
1770                 return -1;
1771         if (!len)
1772                 return -1;
1773         do {
1774                 if (c->stream) {
1775                         d = ast_waitstream(c, AST_DIGIT_ANY);
1776                         ast_stopstream(c);
1777                         usleep(1000);
1778                         if (!d)
1779                                 d = ast_waitfordigit(c, to);
1780                 } else {
1781                         d = ast_waitfordigit(c, to);
1782                 }
1783                 if (d < 0)
1784                         return -1;
1785                 if (d == 0) {
1786                         s[pos]='\0';
1787                         return 1;
1788                 }
1789                 if (!strchr(enders, d))
1790                         s[pos++] = d;
1791                 if (strchr(enders, d) || (pos >= len)) {
1792                         s[pos]='\0';
1793                         return 0;
1794                 }
1795                 to = timeout;
1796         } while(1);
1797         /* Never reached */
1798         return 0;
1799 }
1800
1801 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
1802 {
1803         int pos=0;
1804         int to = ftimeout;
1805         char d;
1806         /* Stop if we're a zombie or need a soft hangup */
1807         if (c->zombie || ast_check_hangup(c)) 
1808                 return -1;
1809         if (!len)
1810                 return -1;
1811         do {
1812                 if (c->stream) {
1813                         d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
1814                         ast_stopstream(c);
1815                         usleep(1000);
1816                         if (!d)
1817                                 d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
1818                 } else {
1819                         d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
1820                 }
1821                 if (d < 0)
1822                         return -1;
1823                 if (d == 0) {
1824                         s[pos]='\0';
1825                         return 1;
1826                 }
1827                 if (d == 1) {
1828                         s[pos]='\0';
1829                         return 2;
1830                 }
1831                 if (!strchr(enders, d))
1832                         s[pos++] = d;
1833                 if (strchr(enders, d) || (pos >= len)) {
1834                         s[pos]='\0';
1835                         return 0;
1836                 }
1837                 to = timeout;
1838         } while(1);
1839         /* Never reached */
1840         return 0;
1841 }
1842
1843 int ast_channel_supports_html(struct ast_channel *chan)
1844 {
1845         if (chan->pvt->send_html)
1846                 return 1;
1847         return 0;
1848 }
1849
1850 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, char *data, int datalen)
1851 {
1852         if (chan->pvt->send_html)
1853                 return chan->pvt->send_html(chan, subclass, data, datalen);
1854         return -1;
1855 }
1856
1857 int ast_channel_sendurl(struct ast_channel *chan, char *url)
1858 {
1859         if (chan->pvt->send_html)
1860                 return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
1861         return -1;
1862 }
1863
1864 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
1865 {
1866         int peerf;
1867         int chanf;
1868         int res;
1869         peerf = peer->nativeformats;
1870         chanf = chan->nativeformats;
1871         res = ast_translator_best_choice(&peerf, &chanf);
1872         if (res < 0) {
1873                 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
1874                 return -1;
1875         }
1876         /* Set read format on channel */
1877         res = ast_set_read_format(chan, peerf);
1878         if (res < 0) {
1879                 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
1880                 return -1;
1881         }
1882         /* Set write format on peer channel */
1883         res = ast_set_write_format(peer, peerf);
1884         if (res < 0) {
1885                 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
1886                 return -1;
1887         }
1888         /* Now we go the other way */
1889         peerf = peer->nativeformats;
1890         chanf = chan->nativeformats;
1891         res = ast_translator_best_choice(&chanf, &peerf);
1892         if (res < 0) {
1893                 ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
1894                 return -1;
1895         }
1896         /* Set writeformat on channel */
1897         res = ast_set_write_format(chan, chanf);
1898         if (res < 0) {
1899                 ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
1900                 return -1;
1901         }
1902         /* Set read format on peer channel */
1903         res = ast_set_read_format(peer, chanf);
1904         if (res < 0) {
1905                 ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
1906                 return -1;
1907         }
1908         return 0;
1909 }
1910
1911 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
1912 {
1913         struct ast_frame null = { AST_FRAME_NULL, };
1914         ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
1915                 clone->name, original->name);
1916         if (original->masq) {
1917                 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
1918                         original->masq->name, original->name);
1919                 return -1;
1920         }
1921         if (clone->masqr) {
1922                 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
1923                         clone->name, clone->masqr->name);
1924                 return -1;
1925         }
1926         original->masq = clone;
1927         clone->masqr = original;
1928         /* XXX can't really hold the lock here, but at the same time, it' s
1929            not really safe not to XXX */
1930         ast_queue_frame(original, &null, 0);
1931         ast_queue_frame(clone, &null, 0);
1932         ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
1933         return 0;
1934 }
1935
1936 void ast_change_name(struct ast_channel *chan, char *newname)
1937 {
1938         char tmp[256];
1939         strncpy(tmp, chan->name, 256);
1940         strncpy(chan->name, newname, sizeof(chan->name) - 1);
1941         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
1942 }
1943
1944 int ast_do_masquerade(struct ast_channel *original, int needlock)
1945 {
1946         int x,i;
1947         int res=0;
1948         char *tmp;
1949         struct ast_var_t *varptr;
1950         struct ast_frame *cur, *prev;
1951         struct ast_channel_pvt *p;
1952         struct ast_channel *clone = original->masq;
1953         int rformat = original->readformat;
1954         int wformat = original->writeformat;
1955         char newn[100];
1956         char orig[100];
1957         char masqn[100];
1958         char zombn[100];
1959         
1960 #if 1
1961         ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
1962                 clone->name, clone->_state, original->name, original->_state);
1963 #endif
1964         /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
1965            the clone channel into the original channel.  Start by killing off the original
1966            channel's backend.   I'm not sure we're going to keep this function, because 
1967            while the features are nice, the cost is very high in terms of pure nastiness. XXX */
1968
1969         if (needlock)
1970                 /* We need the clone's lock, too */
1971                 ast_mutex_lock(&clone->lock);
1972
1973         ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock);
1974
1975         /* Having remembered the original read/write formats, we turn off any translation on either
1976            one */
1977         free_translation(clone);
1978         free_translation(original);
1979
1980
1981         /* Unlink the masquerade */
1982         original->masq = NULL;
1983         clone->masqr = NULL;
1984         
1985         /* Save the original name */
1986         strncpy(orig, original->name, sizeof(orig) - 1);
1987         /* Save the new name */
1988         strncpy(newn, clone->name, sizeof(newn) - 1);
1989         /* Create the masq name */
1990         snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
1991                 
1992         /* Copy the name from the clone channel */
1993         strncpy(original->name, newn, sizeof(original->name)-1);
1994
1995         /* Mangle the name of the clone channel */
1996         strncpy(clone->name, masqn, sizeof(clone->name) - 1);
1997         
1998         /* Notify any managers of the change, first the masq then the other */
1999         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", newn, masqn);
2000         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", orig, newn);
2001
2002         /* Swap the guts */     
2003         p = original->pvt;
2004         original->pvt = clone->pvt;
2005         clone->pvt = p;
2006
2007         /* Save any pending frames on both sides.  Start by counting
2008          * how many we're going to need... */
2009         prev = NULL;
2010         cur = clone->pvt->readq;
2011         x = 0;
2012         while(cur) {
2013                 x++;
2014                 prev = cur;
2015                 cur = cur->next;
2016         }
2017         /* If we had any, prepend them to the ones already in the queue, and 
2018          * load up the alertpipe */
2019         if (prev) {
2020                 prev->next = original->pvt->readq;
2021                 original->pvt->readq = clone->pvt->readq;
2022                 clone->pvt->readq = NULL;
2023                 if (original->pvt->alertpipe[1] > -1) {
2024                         for (i=0;i<x;i++)
2025                                 write(original->pvt->alertpipe[1], &x, sizeof(x));
2026                 }
2027         }
2028         clone->_softhangup = AST_SOFTHANGUP_DEV;
2029
2030
2031         if (clone->pvt->fixup){
2032                 res = clone->pvt->fixup(original, clone, needlock);
2033                 if (res) 
2034                         ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
2035         }
2036
2037         /* Start by disconnecting the original's physical side */
2038         if (clone->pvt->hangup)
2039                 res = clone->pvt->hangup(clone);
2040         if (res) {
2041                 ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
2042                 if (needlock)
2043                         ast_mutex_unlock(&clone->lock);
2044                 return -1;
2045         }
2046         
2047         snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
2048         /* Mangle the name of the clone channel */
2049         strncpy(clone->name, zombn, sizeof(clone->name) - 1);
2050         manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\n", masqn, zombn);
2051
2052         /* Keep the same language.  */
2053         /* Update the type. */
2054         original->type = clone->type;
2055         /* Copy the FD's */
2056         for (x=0;x<AST_MAX_FDS;x++) {
2057                 original->fds[x] = clone->fds[x];
2058         }
2059         /* Append variables from clone channel into original channel */
2060         /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
2061         varptr = original->varshead.first;
2062         if (varptr) {
2063                 while(varptr->entries.next) {
2064                         varptr = varptr->entries.next;
2065                 }
2066                 varptr->entries.next = clone->varshead.first;
2067         } else {
2068                 original->varshead.first = clone->varshead.first;
2069         }
2070         clone->varshead.first = NULL;
2071         /* Presense of ADSI capable CPE follows clone */
2072         original->adsicpe = clone->adsicpe;
2073         /* Bridge remains the same */
2074         /* CDR fields remain the same */
2075         /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
2076         /* Application and data remain the same */
2077         /* Clone exception  becomes real one, as with fdno */
2078         original->exception = clone->exception;
2079         original->fdno = clone->fdno;
2080         /* Schedule context remains the same */
2081         /* Stream stuff stays the same */
2082         /* Keep the original state.  The fixup code will need to work with it most likely */
2083
2084         /* dnid and callerid change to become the new, HOWEVER, we also link the original's
2085            fields back into the defunct 'clone' so that they will be freed when
2086            ast_frfree is eventually called */
2087         tmp = original->dnid;
2088         original->dnid = clone->dnid;
2089         clone->dnid = tmp;
2090         
2091         tmp = original->callerid;
2092         original->callerid = clone->callerid;
2093         clone->callerid = tmp;
2094         
2095         /* Restore original timing file descriptor */
2096         original->fds[AST_MAX_FDS - 2] = original->timingfd;
2097         
2098         /* Our native formats are different now */
2099         original->nativeformats = clone->nativeformats;
2100
2101         /* And of course, so does our current state.  Note we need not
2102            call ast_setstate since the event manager doesn't really consider
2103            these separate */
2104         original->_state = clone->_state;
2105         
2106         /* Context, extension, priority, app data, jump table,  remain the same */
2107         /* pvt switches.  pbx stays the same, as does next */
2108         
2109         /* Set the write format */
2110         ast_set_write_format(original, wformat);
2111
2112         /* Set the read format */
2113         ast_set_read_format(original, rformat);
2114
2115         ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
2116
2117         /* Okay.  Last thing is to let the channel driver know about all this mess, so he
2118            can fix up everything as best as possible */
2119         if (original->pvt->fixup) {
2120                 res = original->pvt->fixup(clone, original, needlock);
2121                 if (res) {
2122                         ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
2123                                 original->type, original->name);
2124                         return -1;
2125                 }
2126         } else
2127                 ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
2128                         original->type, original->name);
2129         
2130         /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
2131            a zombie so nothing tries to touch it.  If it's already been marked as a
2132            zombie, then free it now (since it already is considered invalid). */
2133         if (clone->zombie) {
2134                 ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
2135                 if (needlock)
2136                         ast_mutex_unlock(&clone->lock);
2137                 ast_channel_free(clone);
2138                 manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
2139         } else {
2140                 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
2141                 clone->zombie=1;
2142                 if (needlock)
2143                         ast_mutex_unlock(&clone->lock);
2144         }
2145         
2146         /* Signal any blocker */
2147         if (original->blocking)
2148                 pthread_kill(original->blocker, SIGURG);
2149         ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n",
2150                 original->name, original->_state);
2151         return 0;
2152 }
2153
2154 void ast_set_callerid(struct ast_channel *chan, char *callerid, int anitoo)
2155 {
2156         if (chan->callerid)
2157                 free(chan->callerid);
2158         if (anitoo && chan->ani)
2159                 free(chan->ani);
2160         if (callerid) {
2161                 chan->callerid = strdup(callerid);
2162                 if (anitoo)
2163                         chan->ani = strdup(callerid);
2164         } else {
2165                 chan->callerid = NULL;
2166                 if (anitoo)
2167                         chan->ani = NULL;
2168         }
2169         if (chan->cdr)
2170                 ast_cdr_setcid(chan->cdr, chan);
2171         manager_event(EVENT_FLAG_CALL, "Newcallerid", 
2172                                 "Channel: %s\r\n"
2173                                 "Callerid: %s\r\n"
2174                                 "Uniqueid: %s\r\n",
2175                                 chan->name, chan->callerid ? 
2176                                 chan->callerid : "<Unknown>",
2177                                 chan->uniqueid);
2178 }
2179
2180 int ast_setstate(struct ast_channel *chan, int state)
2181 {
2182         if (chan->_state != state) {
2183                 int oldstate = chan->_state;
2184                 chan->_state = state;
2185                 if (oldstate == AST_STATE_DOWN) {
2186                         ast_device_state_changed(chan->name);
2187                         manager_event(EVENT_FLAG_CALL, "Newchannel",
2188                         "Channel: %s\r\n"
2189                         "State: %s\r\n"
2190                         "Callerid: %s\r\n"
2191                         "Uniqueid: %s\r\n",
2192                         chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
2193                 } else {
2194                         manager_event(EVENT_FLAG_CALL, "Newstate", 
2195                                 "Channel: %s\r\n"
2196                                 "State: %s\r\n"
2197                                 "Callerid: %s\r\n"
2198                                 "Uniqueid: %s\r\n",
2199                                 chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
2200                 }
2201         }
2202         return 0;
2203 }
2204
2205 int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
2206 {
2207         /* Copy voice back and forth between the two channels.  Give the peer
2208            the ability to transfer calls with '#<extension' syntax. */
2209         struct ast_channel *cs[3];
2210         int to = -1;
2211         struct ast_frame *f;
2212         struct ast_channel *who = NULL;
2213         int res;
2214         int nativefailed=0;
2215
2216         /* Stop if we're a zombie or need a soft hangup */
2217         if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 
2218                 return -1;
2219         if (c0->bridge) {
2220                 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
2221                         c0->name, c0->bridge->name);
2222                 return -1;
2223         }
2224         if (c1->bridge) {
2225                 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
2226                         c1->name, c1->bridge->name);
2227                 return -1;
2228         }
2229         
2230         /* Keep track of bridge */
2231         c0->bridge = c1;
2232         c1->bridge = c0;
2233         cs[0] = c0;
2234         cs[1] = c1;
2235         
2236         manager_event(EVENT_FLAG_CALL, "Link", 
2237                         "Channel1: %s\r\n"
2238                         "Channel2: %s\r\n",
2239                         c0->name, c1->name);
2240
2241         for (/* ever */;;) {
2242                 /* Stop if we're a zombie or need a soft hangup */
2243                 if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
2244                         *fo = NULL;
2245                         if (who) *rc = who;
2246                         res = 0;
2247                         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");
2248                         break;
2249                 }
2250                 if (c0->pvt->bridge && 
2251                         (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
2252                                 /* Looks like they share a bridge code */
2253                         if (option_verbose > 2) 
2254                                 ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
2255                         if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
2256                                 c0->bridge = NULL;
2257                                 c1->bridge = NULL;
2258                                 manager_event(EVENT_FLAG_CALL, "Unlink", 
2259                                         "Channel1: %s\r\n"
2260                                         "Channel2: %s\r\n",
2261                                         c0->name, c1->name);
2262                                 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
2263                                 return 0;
2264                         }
2265                         /* If they return non-zero then continue on normally.  Let "-2" mean don't worry about
2266                            my not wanting to bridge */
2267                         if ((res != -2) && (res != -3))
2268                                 ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
2269                         if (res != -3) nativefailed++;
2270                 }
2271         
2272                         
2273                 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat)) &&
2274                         !(c0->generator || c1->generator))  {
2275                         if (ast_channel_make_compatible(c0, c1)) {
2276                                 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
2277                                 manager_event(EVENT_FLAG_CALL, "Unlink", 
2278                                         "Channel1: %s\r\n"
2279                                         "Channel2: %s\r\n",
2280                                         c0->name, c1->name);
2281                                 return -1;
2282                         }
2283                 }
2284                 who = ast_waitfor_n(cs, 2, &to);
2285                 if (!who) {
2286                         ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
2287                         continue;
2288                 }
2289                 f = ast_read(who);
2290                 if (!f) {
2291                         *fo = NULL;
2292                         *rc = who;
2293                         res = 0;
2294                         ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
2295                         break;
2296                 }
2297
2298                 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
2299                         *fo = f;
2300                         *rc = who;
2301                         res =  0;
2302                         ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
2303                         break;
2304                 }
2305                 if ((f->frametype == AST_FRAME_VOICE) ||
2306                         (f->frametype == AST_FRAME_TEXT) ||
2307                         (f->frametype == AST_FRAME_VIDEO) || 
2308                         (f->frametype == AST_FRAME_IMAGE) ||
2309                         (f->frametype == AST_FRAME_DTMF)) {
2310                         if ((f->frametype == AST_FRAME_DTMF) && 
2311                                 (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
2312                                 if ((who == c0)) {
2313                                         if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
2314                                                 *rc = c0;
2315                                                 *fo = f;
2316                                                 /* Take out of conference mode */
2317                                                 res = 0;
2318                                                 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
2319                                                 break;
2320                                         } else 
2321                                                 goto tackygoto;
2322                                 } else
2323                                 if ((who == c1)) {
2324                                         if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
2325                                                 *rc = c1;
2326                                                 *fo = f;
2327                                                 res =  0;
2328                                                 ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
2329                                                 break;
2330                                         } else
2331                                                 goto tackygoto;
2332                                 }
2333                         } else {
2334 #if 0
2335                                 ast_log(LOG_DEBUG, "Read from %s\n", who->name);
2336                                 if (who == last) 
2337                                         ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
2338                                 last = who;
2339 #endif
2340 tackygoto:
2341                                 /* Don't copy packets if there is a generator on either one, since they're
2342                                    not supposed to be listening anyway */
2343                                 if (who == c0) 
2344                                         ast_write(c1, f);
2345                                 else 
2346                                         ast_write(c0, f);
2347                         }
2348                         ast_frfree(f);
2349                 } else
2350                         ast_frfree(f);
2351                 /* Swap who gets priority */
2352                 cs[2] = cs[0];
2353                 cs[0] = cs[1];
2354                 cs[1] = cs[2];
2355         }
2356         c0->bridge = NULL;
2357         c1->bridge = NULL;
2358         manager_event(EVENT_FLAG_CALL, "Unlink", 
2359                                         "Channel1: %s\r\n"
2360                                         "Channel2: %s\r\n",
2361                                         c0->name, c1->name);
2362         ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
2363         return res;
2364 }
2365
2366 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
2367 {
2368         int res;
2369         if (chan->pvt->setoption) {
2370                 res = chan->pvt->setoption(chan, option, data, datalen);
2371                 if (res < 0)
2372                         return res;
2373         } else {
2374                 errno = ENOSYS;
2375                 return -1;
2376         }
2377         if (block) {
2378                 /* XXX Implement blocking -- just wait for our option frame reply, discarding
2379                    intermediate packets. XXX */
2380                 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
2381                 return -1;
2382         }
2383         return 0;
2384 }
2385
2386 struct tonepair_def {
2387         int freq1;
2388         int freq2;
2389         int duration;
2390         int vol;
2391 };
2392
2393 struct tonepair_state {
2394         float freq1;
2395         float freq2;
2396         float vol;
2397         int duration;
2398         int pos;
2399         int origwfmt;
2400         struct ast_frame f;
2401         unsigned char offset[AST_FRIENDLY_OFFSET];
2402         short data[4000];
2403 };
2404
2405 static void tonepair_release(struct ast_channel *chan, void *params)
2406 {
2407         struct tonepair_state *ts = params;
2408         if (chan) {
2409                 ast_set_write_format(chan, ts->origwfmt);
2410         }
2411         free(ts);
2412 }
2413
2414 static void * tonepair_alloc(struct ast_channel *chan, void *params)
2415 {
2416         struct tonepair_state *ts;
2417         struct tonepair_def *td = params;
2418         ts = malloc(sizeof(struct tonepair_state));
2419         if (!ts)
2420                 return NULL;
2421         memset(ts, 0, sizeof(struct tonepair_state));
2422         ts->origwfmt = chan->writeformat;
2423         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
2424                 ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
2425                 tonepair_release(NULL, ts);
2426                 ts = NULL;
2427         } else {
2428                 ts->freq1 = td->freq1;
2429                 ts->freq2 = td->freq2;
2430                 ts->duration = td->duration;
2431                 ts->vol = td->vol;
2432         }
2433         /* Let interrupts interrupt :) */
2434         chan->writeinterrupt = 1;
2435         return ts;
2436 }
2437
2438 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
2439 {
2440         struct tonepair_state *ts = data;
2441         int x;
2442
2443         /* we need to prepare a frame with 16 * timelen samples as we're 
2444          * generating SLIN audio
2445          */
2446         len = samples * 2;
2447
2448         if (len > sizeof(ts->data) / 2 - 1) {
2449                 ast_log(LOG_WARNING, "Can't generate that much data!\n");
2450                 return -1;
2451         }
2452         memset(&ts->f, 0, sizeof(ts->f));
2453         for (x=0;x<len/2;x++) {
2454                 ts->data[x] = ts->vol * (
2455                                 sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
2456                                 sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
2457                         );
2458         }
2459         ts->f.frametype = AST_FRAME_VOICE;
2460         ts->f.subclass = AST_FORMAT_SLINEAR;
2461         ts->f.datalen = len;
2462         ts->f.samples = samples;
2463         ts->f.offset = AST_FRIENDLY_OFFSET;
2464         ts->f.data = ts->data;
2465         ast_write(chan, &ts->f);
2466         ts->pos += x;
2467         if (ts->duration > 0) {
2468                 if (ts->pos >= ts->duration * 8)
2469                         return -1;
2470         }
2471         return 0;
2472 }
2473
2474 static struct ast_generator tonepair = {
2475         alloc: tonepair_alloc,
2476         release: tonepair_release,
2477         generate: tonepair_generator,
2478 };
2479
2480 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
2481 {
2482         struct tonepair_def d = { 0, };
2483         d.freq1 = freq1;
2484         d.freq2 = freq2;
2485         d.duration = duration;
2486         if (vol < 1)
2487                 d.vol = 8192;
2488         else
2489                 d.vol = vol;
2490         if (ast_activate_generator(chan, &tonepair, &d))
2491                 return -1;
2492         return 0;
2493 }
2494
2495 void ast_tonepair_stop(struct ast_channel *chan)
2496 {
2497         ast_deactivate_generator(chan);
2498 }
2499
2500 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
2501 {
2502         struct ast_frame *f;
2503         int res;
2504         if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
2505                 return res;
2506
2507         /* Give us some wiggle room */
2508         while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
2509                 f = ast_read(chan);
2510                 if (f)
2511                         ast_frfree(f);
2512                 else
2513                         return -1;
2514         }
2515         return 0;
2516 }
2517
2518 unsigned int ast_get_group(char *s)
2519 {
2520         char *copy;
2521         char *piece;
2522         char *c=NULL;
2523         int start=0, finish=0,x;
2524         unsigned int group = 0;
2525         copy = ast_strdupa(s);
2526         if (!copy) {
2527                 ast_log(LOG_ERROR, "Out of memory\n");
2528                 return 0;
2529         }
2530         c = copy;
2531         
2532         while((piece = strsep(&c, ","))) {
2533                 if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
2534                         /* Range */
2535                 } else if (sscanf(piece, "%d", &start)) {
2536                         /* Just one */
2537                         finish = start;
2538                 } else {
2539                         ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.  Using '0'\n", s,piece);
2540                         return 0;
2541                 }
2542                 for (x=start;x<=finish;x++) {
2543                         if ((x > 31) || (x < 0)) {
2544                                 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x);
2545                         } else
2546                                 group |= (1 << x);
2547                 }
2548         }
2549         return group;
2550 }