Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

channel.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- A telephony toolkit for Linux.
00003  *
00004  * Channel Management
00005  * 
00006  * Copyright (C) 1999-2004, Digium, Inc.
00007  *
00008  * Mark Spencer <markster@digium.com>
00009  *
00010  * This program is free software, distributed under the terms of
00011  * the GNU General Public License
00012  */
00013 
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <sys/time.h>
00018 #include <signal.h>
00019 #include <errno.h>
00020 #include <unistd.h>
00021 #include <math.h>       /* For PI */
00022 #include <sys/poll.h>
00023 #include <asterisk/pbx.h>
00024 #include <asterisk/frame.h>
00025 #include <asterisk/sched.h>
00026 #include <asterisk/options.h>
00027 #include <asterisk/channel.h>
00028 #include <asterisk/channel_pvt.h>
00029 #include <asterisk/logger.h>
00030 #include <asterisk/say.h>
00031 #include <asterisk/file.h>
00032 #include <asterisk/translate.h>
00033 #include <asterisk/manager.h>
00034 #include <asterisk/chanvars.h>
00035 #include <asterisk/linkedlists.h>
00036 #include <asterisk/indications.h>
00037 #include <asterisk/monitor.h>
00038 #include <asterisk/causes.h>
00039 #include <asterisk/utils.h>
00040 #include <asterisk/lock.h>
00041 #include "astconf.h"
00042 #ifdef ZAPTEL_OPTIMIZATIONS
00043 #include <sys/ioctl.h>
00044 #ifdef __linux__
00045 #include <linux/zaptel.h>
00046 #else
00047 #include <zaptel.h>
00048 #endif /* __linux__ */
00049 #ifndef ZT_TIMERPING
00050 #error "You need newer zaptel!  Please cvs update zaptel"
00051 #endif
00052 #endif
00053 
00054 /* uncomment if you have problems with 'monitoring' synchronized files */
00055 #if 0
00056 #define MONITOR_CONSTANT_DELAY
00057 #define MONITOR_DELAY   150 * 8     /* 150 ms of MONITORING DELAY */
00058 #endif
00059 
00060 extern int ast_mainpid; /* provided by asterisk.c */
00061 static int shutting_down = 0;
00062 static int uniqueint = 0;
00063 AST_MUTEX_DEFINE_STATIC(uniquelock);
00064 
00065 /* XXX Lock appropriately in more functions XXX */
00066 
00067 struct chanlist {
00068    char type[80];
00069    char description[80];
00070    int capabilities;
00071    struct ast_channel * (*requester)(char *type, int format, void *data);
00072    int (*devicestate)(void *data);
00073    struct chanlist *next;
00074 } *backends = NULL;
00075 struct ast_channel *channels = NULL;
00076 
00077 /* Protect the channel list (highly unlikely that two things would change
00078    it at the same time, but still! */
00079    
00080 AST_MUTEX_DEFINE_STATIC(chlock);
00081 
00082 int ast_check_hangup(struct ast_channel *chan)
00083 {
00084 time_t   myt;
00085 
00086      /* if soft hangup flag, return true */
00087    if (chan->_softhangup) return 1;
00088      /* if no private structure, return true */
00089    if (!chan->pvt->pvt) return 1;
00090      /* if no hangup scheduled, just return here */
00091    if (!chan->whentohangup) return 0;
00092    time(&myt); /* get current time */
00093      /* return, if not yet */
00094    if (chan->whentohangup > myt) return 0;
00095    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00096    return 1;
00097 }
00098 
00099 static int ast_check_hangup_locked(struct ast_channel *chan)
00100 {
00101    int res;
00102    ast_mutex_lock(&chan->lock);
00103    res = ast_check_hangup(chan);
00104    ast_mutex_unlock(&chan->lock);
00105    return res;
00106 }
00107 
00108 void ast_begin_shutdown(int hangup)
00109 {
00110    struct ast_channel *c;
00111    shutting_down = 1;
00112    if (hangup) {
00113       ast_mutex_lock(&chlock);
00114       c = channels;
00115       while(c) {
00116          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00117          c = c->next;
00118       }
00119       ast_mutex_unlock(&chlock);
00120    }
00121 }
00122 
00123 int ast_active_channels(void)
00124 {
00125    struct ast_channel *c;
00126    int cnt = 0;
00127    ast_mutex_lock(&chlock);
00128    c = channels;
00129    while(c) {
00130       cnt++;
00131       c = c->next;
00132    }
00133    ast_mutex_unlock(&chlock);
00134    return cnt;
00135 }
00136 
00137 void ast_cancel_shutdown(void)
00138 {
00139    shutting_down = 0;
00140 }
00141 
00142 int ast_shutting_down(void)
00143 {
00144    return shutting_down;
00145 }
00146 
00147 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00148 {
00149    time_t   myt;
00150 
00151    time(&myt);
00152    if (offset)
00153       chan->whentohangup = myt + offset;
00154    else
00155       chan->whentohangup = 0;
00156    return;
00157 }
00158 
00159 int ast_channel_register(char *type, char *description, int capabilities,
00160       struct ast_channel *(*requester)(char *type, int format, void *data))
00161 {
00162    return ast_channel_register_ex(type, description, capabilities, requester, NULL);
00163 }
00164 
00165 int ast_channel_register_ex(char *type, char *description, int capabilities,
00166       struct ast_channel *(*requester)(char *type, int format, void *data),
00167       int (*devicestate)(void *data))
00168 {
00169    struct chanlist *chan, *last=NULL;
00170    if (ast_mutex_lock(&chlock)) {
00171       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00172       return -1;
00173    }
00174    chan = backends;
00175    while (chan) {
00176       if (!strcasecmp(type, chan->type)) {
00177          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
00178          ast_mutex_unlock(&chlock);
00179          return -1;
00180       }
00181       last = chan;
00182       chan = chan->next;
00183    }
00184    chan = malloc(sizeof(struct chanlist));
00185    if (!chan) {
00186       ast_log(LOG_WARNING, "Out of memory\n");
00187       ast_mutex_unlock(&chlock);
00188       return -1;
00189    }
00190    strncpy(chan->type, type, sizeof(chan->type)-1);
00191    strncpy(chan->description, description, sizeof(chan->description)-1);
00192    chan->capabilities = capabilities;
00193    chan->requester = requester;
00194    chan->devicestate = devicestate;
00195    chan->next = NULL;
00196    if (last)
00197       last->next = chan;
00198    else
00199       backends = chan;
00200    if (option_debug)
00201       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
00202    else if (option_verbose > 1)
00203       ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
00204    ast_mutex_unlock(&chlock);
00205    return 0;
00206 }
00207 
00208 char *ast_state2str(int state)
00209 {
00210    /* XXX Not reentrant XXX */
00211    static char localtmp[256];
00212    switch(state) {
00213    case AST_STATE_DOWN:
00214       return "Down";
00215    case AST_STATE_RESERVED:
00216       return "Rsrvd";
00217    case AST_STATE_OFFHOOK:
00218       return "OffHook";
00219    case AST_STATE_DIALING:
00220       return "Dialing";
00221    case AST_STATE_RING:
00222       return "Ring";
00223    case AST_STATE_RINGING:
00224       return "Ringing";
00225    case AST_STATE_UP:
00226       return "Up";
00227    case AST_STATE_BUSY:
00228       return "Busy";
00229    default:
00230       snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00231       return localtmp;
00232    }
00233 }
00234 
00235 
00236 int ast_best_codec(int fmts)
00237 {
00238    /* This just our opinion, expressed in code.  We are asked to choose
00239       the best codec to use, given no information */
00240    int x;
00241    static int prefs[] = 
00242    {
00243       /* Okay, ulaw is used by all telephony equipment, so start with it */
00244       AST_FORMAT_ULAW,
00245       /* Unless of course, you're a silly European, so then prefer ALAW */
00246       AST_FORMAT_ALAW,
00247       /* Okay, well, signed linear is easy to translate into other stuff */
00248       AST_FORMAT_SLINEAR,
00249       /* G.726 is standard ADPCM */
00250       AST_FORMAT_G726,
00251       /* ADPCM has great sound quality and is still pretty easy to translate */
00252       AST_FORMAT_ADPCM,
00253       /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00254          translate and sounds pretty good */
00255       AST_FORMAT_GSM,
00256       /* iLBC is not too bad */
00257       AST_FORMAT_ILBC,
00258       /* Speex is free, but computationally more expensive than GSM */
00259       AST_FORMAT_SPEEX,
00260       /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00261          to use it */
00262       AST_FORMAT_LPC10,
00263       /* G.729a is faster than 723 and slightly less expensive */
00264       AST_FORMAT_G729A,
00265       /* Down to G.723.1 which is proprietary but at least designed for voice */
00266       AST_FORMAT_G723_1,
00267    };
00268    
00269    
00270    for (x=0;x<sizeof(prefs) / sizeof(prefs[0]); x++)
00271       if (fmts & prefs[x])
00272          return prefs[x];
00273    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00274    return 0;
00275 }
00276 
00277 char *ast_alloc_uniqueid(void) {
00278     char *uniqueid;
00279     uniqueid = malloc(64);
00280     if (!uniqueid) return NULL;
00281     ast_mutex_lock(&uniquelock);
00282     snprintf(uniqueid, 63, "%s-%d-%li.%d", ast_config_AST_SYMBOLIC_NAME, ast_mainpid, (long)time(NULL), uniqueint++);
00283     ast_mutex_unlock(&uniquelock);
00284 //    ast_log(LOG_NOTICE,"uid = %s\n",uniqueid);
00285     return uniqueid;
00286 }
00287 
00288 struct ast_channel *ast_channel_alloc(int needqueue)
00289 {
00290    struct ast_channel *tmp;
00291    struct ast_channel_pvt *pvt;
00292    int x;
00293    int flags;
00294    struct varshead *headp;
00295    char *tmpuniqueid;
00296            
00297    
00298    /* If shutting down, don't allocate any new channels */
00299    if (shutting_down)
00300       return NULL;
00301    ast_mutex_lock(&chlock);
00302    tmp = malloc(sizeof(struct ast_channel));
00303    if (tmp) {
00304       memset(tmp, 0, sizeof(struct ast_channel));
00305       pvt = malloc(sizeof(struct ast_channel_pvt));
00306       if (pvt) {
00307          memset(pvt, 0, sizeof(struct ast_channel_pvt));
00308          tmp->sched = sched_context_create();
00309          if (tmp->sched) {
00310             for (x=0;x<AST_MAX_FDS - 1;x++)
00311                tmp->fds[x] = -1;
00312 #ifdef ZAPTEL_OPTIMIZATIONS
00313             tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00314             if (tmp->timingfd > -1) {
00315                /* Check if timing interface supports new
00316                   ping/pong scheme */
00317                flags = 1;
00318                if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00319                   needqueue = 0;
00320             }
00321 #else
00322             tmp->timingfd = -1;              
00323 #endif               
00324             if (needqueue &&  
00325                pipe(pvt->alertpipe)) {
00326                ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
00327                free(pvt);
00328                free(tmp);
00329                tmp = NULL;
00330                pvt = NULL;
00331             } else {
00332                if (needqueue) {
00333                   flags = fcntl(pvt->alertpipe[0], F_GETFL);
00334                   fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00335                   flags = fcntl(pvt->alertpipe[1], F_GETFL);
00336                   fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00337                } else 
00338                /* Make sure we've got it done right if they don't */
00339                   pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
00340                /* Always watch the alertpipe */
00341                tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
00342                /* And timing pipe */
00343                tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00344                strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
00345                tmp->pvt = pvt;
00346                /* Initial state */
00347                tmp->_state = AST_STATE_DOWN;
00348                tmp->stack = -1;
00349                tmp->streamid = -1;
00350                tmp->appl = NULL;
00351                tmp->data = NULL;
00352                tmp->fin = 0;
00353                tmp->fout = 0;
00354                tmpuniqueid = ast_alloc_uniqueid();
00355                snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), tmpuniqueid);
00356                if (tmpuniqueid) { 
00357                    free(tmpuniqueid);
00358                    tmpuniqueid = NULL;
00359                }
00360                headp=&tmp->varshead;
00361                ast_mutex_init(&tmp->lock);
00362                     AST_LIST_HEAD_INIT(headp);
00363                tmp->vars=ast_var_assign("tempvar","tempval");
00364                AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
00365                strncpy(tmp->context, "default", sizeof(tmp->context)-1);
00366                strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
00367                strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
00368                tmp->priority=1;
00369                tmp->amaflags = ast_default_amaflags;
00370                strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
00371                tmp->next = channels;
00372                channels= tmp;
00373             }
00374          } else {
00375             ast_log(LOG_WARNING, "Unable to create schedule context\n");
00376             free(tmp);
00377             tmp = NULL;
00378          }
00379       } else {
00380          ast_log(LOG_WARNING, "Out of memory\n");
00381          free(tmp);
00382          tmp = NULL;
00383       }
00384    } else 
00385       ast_log(LOG_WARNING, "Out of memory\n");
00386    ast_mutex_unlock(&chlock);
00387    return tmp;
00388 }
00389 
00390 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
00391 {
00392    struct ast_frame *f;
00393    struct ast_frame *prev, *cur;
00394    int blah = 1;
00395    int qlen = 0;
00396    /* Build us a copy and free the original one */
00397    f = ast_frdup(fin);
00398    if (!f) {
00399       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00400       return -1;
00401    }
00402    ast_mutex_lock(&chan->lock);
00403    prev = NULL;
00404    cur = chan->pvt->readq;
00405    while(cur) {
00406       if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00407          /* Don't bother actually queueing anything after a hangup */
00408          ast_frfree(f);
00409          ast_mutex_unlock(&chan->lock);
00410          return 0;
00411       }
00412       prev = cur;
00413       cur = cur->next;
00414       qlen++;
00415    }
00416    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00417    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
00418       if (fin->frametype != AST_FRAME_VOICE) {
00419          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00420          CRASH;
00421       } else {
00422          ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00423          ast_frfree(f);
00424          ast_mutex_unlock(&chan->lock);
00425          return 0;
00426       }
00427    }
00428    if (prev)
00429       prev->next = f;
00430    else
00431       chan->pvt->readq = f;
00432    if (chan->pvt->alertpipe[1] > -1) {
00433       if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00434          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00435             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00436 #ifdef ZAPTEL_OPTIMIZATIONS
00437    } else if (chan->timingfd > -1) {
00438       ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00439 #endif            
00440    } else if (chan->blocking) {
00441       pthread_kill(chan->blocker, SIGURG);
00442    }
00443    ast_mutex_unlock(&chan->lock);
00444    return 0;
00445 }
00446 
00447 int ast_queue_hangup(struct ast_channel *chan)
00448 {
00449    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00450    chan->_softhangup |= AST_SOFTHANGUP_DEV;
00451    return ast_queue_frame(chan, &f);
00452 }
00453 
00454 int ast_queue_control(struct ast_channel *chan, int control)
00455 {
00456    struct ast_frame f = { AST_FRAME_CONTROL, };
00457    f.subclass = control;
00458    return ast_queue_frame(chan, &f);
00459 }
00460 
00461 int ast_channel_defer_dtmf(struct ast_channel *chan)
00462 {
00463    int pre = 0;
00464    if (chan) {
00465       pre = chan->deferdtmf;
00466       chan->deferdtmf = 1;
00467    }
00468    return pre;
00469 }
00470 
00471 void ast_channel_undefer_dtmf(struct ast_channel *chan)
00472 {
00473    if (chan)
00474       chan->deferdtmf = 0;
00475 }
00476 
00477 struct ast_channel *ast_channel_walk_locked(struct ast_channel *prev)
00478 {
00479    /* Returns next channel (locked) */
00480    struct ast_channel *l, *ret;
00481    int retries = 0;  
00482 retry:
00483    ret=NULL;
00484    ast_mutex_lock(&chlock);
00485    l = channels;
00486    if (!prev) {
00487       if (l) {
00488          if (ast_mutex_trylock(&l->lock)) {
00489             if (retries < 10)
00490                ast_log(LOG_DEBUG, "Avoiding initial deadlock for '%s'\n", l->name);
00491             else
00492                ast_log(LOG_WARNING, "Avoided initial deadlock for '%s', %d retries!\n", l->name, retries);
00493             ast_mutex_unlock(&chlock);
00494             if (retries < 10) {
00495                usleep(1);
00496                retries++;
00497                goto retry;
00498             } else
00499                return NULL;
00500          }
00501       }
00502       ast_mutex_unlock(&chlock);
00503       return l;
00504    }
00505    while(l) {
00506       if (l == prev)
00507          ret = l->next;
00508       l = l->next;
00509    }
00510    if (ret) {
00511       if (ast_mutex_trylock(&ret->lock)) {
00512          if (retries < 10)
00513             ast_log(LOG_DEBUG, "Avoiding deadlock for '%s'\n", ret->name);
00514          else
00515             ast_log(LOG_WARNING, "Avoided deadlock for '%s', %d retries!\n", ret->name, retries);
00516          ast_mutex_unlock(&chlock);
00517          if (retries < 10) {
00518             usleep(1);
00519             retries++;
00520             goto retry;
00521          } else
00522             return NULL;
00523       }
00524    }
00525    ast_mutex_unlock(&chlock);
00526    return ret;
00527    
00528 }
00529 
00530 struct ast_channel *ast_get_channel_by_name_locked(char *channame)
00531 {
00532    struct ast_channel *chan;
00533    chan = ast_channel_walk_locked(NULL);
00534    while(chan) {
00535       if (!strcasecmp(chan->name, channame))
00536          return chan;
00537       ast_mutex_unlock(&chan->lock);
00538       chan = ast_channel_walk_locked(chan);
00539    }
00540    return NULL;
00541 }
00542 
00543 struct ast_channel *ast_get_channel_by_uniqueid_locked(char *uniqueid)
00544 {
00545    struct ast_channel *chan;
00546    chan = ast_channel_walk_locked(NULL);
00547    while(chan) {
00548       if (!strcasecmp(chan->uniqueid, uniqueid))
00549          return chan;
00550       ast_mutex_unlock(&chan->lock);
00551       chan = ast_channel_walk_locked(chan);
00552    }
00553    return NULL;
00554 }
00555 
00556 int ast_safe_sleep_conditional(  struct ast_channel *chan, int ms,
00557                         int (*cond)(void*), void *data )
00558 {
00559    struct ast_frame *f;
00560 
00561    while(ms > 0) {
00562       if( cond && ((*cond)(data) == 0 ) )
00563          return 0;
00564       ms = ast_waitfor(chan, ms);
00565       if (ms <0)
00566          return -1;
00567       if (ms > 0) {
00568          f = ast_read(chan);
00569          if (!f)
00570             return -1;
00571          ast_frfree(f);
00572       }
00573    }
00574    return 0;
00575 }
00576 
00577 int ast_safe_sleep(struct ast_channel *chan, int ms)
00578 {
00579    struct ast_frame *f;
00580    while(ms > 0) {
00581       ms = ast_waitfor(chan, ms);
00582       if (ms <0)
00583          return -1;
00584       if (ms > 0) {
00585          f = ast_read(chan);
00586          if (!f)
00587             return -1;
00588          ast_frfree(f);
00589       }
00590    }
00591    return 0;
00592 }
00593 
00594 void ast_channel_free(struct ast_channel *chan)
00595 {
00596    struct ast_channel *last=NULL, *cur;
00597    int fd;
00598    struct ast_var_t *vardata;
00599    struct ast_frame *f, *fp;
00600    struct varshead *headp;
00601    char name[AST_CHANNEL_NAME];
00602    
00603    headp=&chan->varshead;
00604    
00605    ast_mutex_lock(&chlock);
00606    cur = channels;
00607    while(cur) {
00608       if (cur == chan) {
00609          if (last)
00610             last->next = cur->next;
00611          else
00612             channels = cur->next;
00613          break;
00614       }
00615       last = cur;
00616       cur = cur->next;
00617    }
00618    if (!cur)
00619       ast_log(LOG_WARNING, "Unable to find channel in list\n");
00620    else {
00621       /* Lock and unlock the channel just to be sure nobody
00622          has it locked still */
00623       ast_mutex_lock(&cur->lock);
00624       ast_mutex_unlock(&cur->lock);
00625    }
00626    if (chan->pvt->pvt)
00627       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00628 
00629    strncpy(name, chan->name, sizeof(name)-1);
00630    
00631    /* Stop monitoring */
00632    if (chan->monitor) {
00633       chan->monitor->stop( chan, 0 );
00634    }
00635 
00636    /* Free translatosr */
00637    if (chan->pvt->readtrans)
00638       ast_translator_free_path(chan->pvt->readtrans);
00639    if (chan->pvt->writetrans)
00640       ast_translator_free_path(chan->pvt->writetrans);
00641    if (chan->pbx) 
00642       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00643    if (chan->dnid)
00644       free(chan->dnid);
00645    if (chan->callerid)
00646       free(chan->callerid);   
00647    if (chan->ani)
00648       free(chan->ani);
00649    if (chan->rdnis)
00650       free(chan->rdnis);
00651    ast_mutex_destroy(&chan->lock);
00652    /* Close pipes if appropriate */
00653    if ((fd = chan->pvt->alertpipe[0]) > -1)
00654       close(fd);
00655    if ((fd = chan->pvt->alertpipe[1]) > -1)
00656       close(fd);
00657    if ((fd = chan->timingfd) > -1)
00658       close(fd);
00659    f = chan->pvt->readq;
00660    chan->pvt->readq = NULL;
00661    while(f) {
00662       fp = f;
00663       f = f->next;
00664       ast_frfree(fp);
00665    }
00666    
00667    /* loop over the variables list, freeing all data and deleting list items */
00668    /* no need to lock the list, as the channel is already locked */
00669    
00670    while (!AST_LIST_EMPTY(headp)) {           /* List Deletion. */
00671                vardata = AST_LIST_FIRST(headp);
00672                AST_LIST_REMOVE_HEAD(headp, entries);
00673 //             printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
00674                ast_var_delete(vardata);
00675    }
00676                                                     
00677 
00678    free(chan->pvt);
00679    chan->pvt = NULL;
00680    free(chan);
00681    ast_mutex_unlock(&chlock);
00682 
00683    ast_device_state_changed(name);
00684 }
00685 
00686 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
00687 {
00688    int res = 0;
00689    struct ast_frame f = { AST_FRAME_NULL };
00690    if (option_debug)
00691       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
00692    /* Inform channel driver that we need to be hung up, if it cares */
00693    chan->_softhangup |= cause;
00694    ast_queue_frame(chan, &f);
00695    /* Interrupt any poll call or such */
00696    if (chan->blocking)
00697       pthread_kill(chan->blocker, SIGURG);
00698    return res;
00699 }
00700 
00701 int ast_softhangup(struct ast_channel *chan, int cause)
00702 {
00703    int res;
00704    ast_mutex_lock(&chan->lock);
00705    res = ast_softhangup_nolock(chan, cause);
00706    ast_mutex_unlock(&chan->lock);
00707    return res;
00708 }
00709 
00710 static void free_translation(struct ast_channel *clone)
00711 {
00712    if (clone->pvt->writetrans)
00713       ast_translator_free_path(clone->pvt->writetrans);
00714    if (clone->pvt->readtrans)
00715       ast_translator_free_path(clone->pvt->readtrans);
00716    clone->pvt->writetrans = NULL;
00717    clone->pvt->readtrans = NULL;
00718    clone->pvt->rawwriteformat = clone->nativeformats;
00719    clone->pvt->rawreadformat = clone->nativeformats;
00720 }
00721 
00722 int ast_hangup(struct ast_channel *chan)
00723 {
00724    int res = 0;
00725    /* Don't actually hang up a channel that will masquerade as someone else, or
00726       if someone is going to masquerade as us */
00727    ast_mutex_lock(&chan->lock);
00728    if (chan->masq) {
00729       if (ast_do_masquerade(chan)) 
00730          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
00731    }
00732 
00733    if (chan->masq) {
00734       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
00735       ast_mutex_unlock(&chan->lock);
00736       return 0;
00737    }
00738    /* If this channel is one which will be masqueraded into something, 
00739       mark it as a zombie already, so we know to free it later */
00740    if (chan->masqr) {
00741       chan->zombie=1;
00742       ast_mutex_unlock(&chan->lock);
00743       return 0;
00744    }
00745    free_translation(chan);
00746    if (chan->stream) 
00747       ast_closestream(chan->stream);
00748    if (chan->vstream)
00749       ast_closestream(chan->vstream);
00750    if (chan->sched)
00751       sched_context_destroy(chan->sched);
00752    /* Clear any tone stuff remaining */
00753    if (chan->generatordata)
00754       chan->generator->release(chan, chan->generatordata);
00755    chan->generatordata = NULL;
00756    chan->generator = NULL;
00757    if (chan->cdr) {
00758       /* End the CDR if it hasn't already */
00759       ast_cdr_end(chan->cdr);
00760       /* Post and Free the CDR */
00761       ast_cdr_post(chan->cdr);
00762       ast_cdr_free(chan->cdr);
00763    }
00764    if (chan->blocking) {
00765       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
00766                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
00767                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
00768       CRASH;
00769    }
00770    if (!chan->zombie) {
00771       if (option_debug)
00772          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
00773       if (chan->pvt->hangup)
00774          res = chan->pvt->hangup(chan);
00775    } else
00776       if (option_debug)
00777          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
00778          
00779    ast_mutex_unlock(&chan->lock);
00780    manager_event(EVENT_FLAG_CALL, "Hangup", 
00781          "Channel: %s\r\n"
00782          "Uniqueid: %s\r\n"
00783          "Cause: %i\r\n",
00784          chan->name, chan->uniqueid, chan->hangupcause);
00785    ast_channel_free(chan);
00786    return res;
00787 }
00788 
00789 void ast_channel_unregister(char *type)
00790 {
00791    struct chanlist *chan, *last=NULL;
00792    if (option_debug)
00793       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
00794    if (ast_mutex_lock(&chlock)) {
00795       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00796       return;
00797    }
00798    if (option_verbose > 1)
00799       ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type);
00800 
00801    chan = backends;
00802    while(chan) {
00803       if (!strcasecmp(chan->type, type)) {
00804          if (last)
00805             last->next = chan->next;
00806          else
00807             backends = backends->next;
00808          free(chan);
00809          ast_mutex_unlock(&chlock);
00810          return;
00811       }
00812       last = chan;
00813       chan = chan->next;
00814    }
00815    ast_mutex_unlock(&chlock);
00816 }
00817 
00818 int ast_answer(struct ast_channel *chan)
00819 {
00820    int res = 0;
00821    ast_mutex_lock(&chan->lock);
00822    /* Stop if we're a zombie or need a soft hangup */
00823    if (chan->zombie || ast_check_hangup(chan)) {
00824       ast_mutex_unlock(&chan->lock);
00825       return -1;
00826    }
00827    switch(chan->_state) {
00828    case AST_STATE_RINGING:
00829    case AST_STATE_RING:
00830       if (chan->pvt->answer)
00831          res = chan->pvt->answer(chan);
00832       ast_setstate(chan, AST_STATE_UP);
00833       if (chan->cdr)
00834          ast_cdr_answer(chan->cdr);
00835       ast_mutex_unlock(&chan->lock);
00836       return res;
00837       break;
00838    case AST_STATE_UP:
00839       if (chan->cdr)
00840          ast_cdr_answer(chan->cdr);
00841       break;
00842    }
00843    ast_mutex_unlock(&chan->lock);
00844    return 0;
00845 }
00846 
00847 
00848 
00849 void ast_deactivate_generator(struct ast_channel *chan)
00850 {
00851    ast_mutex_lock(&chan->lock);
00852    if (chan->generatordata) {
00853       if (chan->generator && chan->generator->release) 
00854          chan->generator->release(chan, chan->generatordata);
00855       chan->generatordata = NULL;
00856       chan->generator = NULL;
00857       chan->writeinterrupt = 0;
00858       ast_settimeout(chan, 0, NULL, NULL);
00859    }
00860    ast_mutex_unlock(&chan->lock);
00861 }
00862 
00863 static int generator_force(void *data)
00864 {
00865    /* Called if generator doesn't have data */
00866    void *tmp;
00867    int res;
00868    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
00869    struct ast_channel *chan = data;
00870    tmp = chan->generatordata;
00871    chan->generatordata = NULL;
00872    generate = chan->generator->generate;
00873    res = generate(chan, tmp, 0, 160);
00874    chan->generatordata = tmp;
00875    if (res) {
00876       ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
00877       ast_deactivate_generator(chan);
00878    }
00879    return 0;
00880 }
00881 
00882 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
00883 {
00884    int res = 0;
00885    ast_mutex_lock(&chan->lock);
00886    if (chan->generatordata) {
00887       if (chan->generator && chan->generator->release)
00888          chan->generator->release(chan, chan->generatordata);
00889       chan->generatordata = NULL;
00890    }
00891    ast_prod(chan);
00892    if ((chan->generatordata = gen->alloc(chan, params))) {
00893       ast_settimeout(chan, 160, generator_force, chan);
00894       chan->generator = gen;
00895    } else {
00896       res = -1;
00897    }
00898    ast_mutex_unlock(&chan->lock);
00899    return res;
00900 }
00901 
00902 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
00903 {
00904    /* Wait for x amount of time on a file descriptor to have input.  */
00905    struct timeval start, now;
00906    int res;
00907    int x, y;
00908    int winner = -1;
00909    int spoint;
00910    struct pollfd *pfds;
00911    
00912    pfds = alloca(sizeof(struct pollfd) * n);
00913    if (!pfds) {
00914       ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
00915       return -1;
00916    }
00917    if (*ms > 0)
00918       gettimeofday(&start, NULL);
00919    y = 0;
00920    for (x=0;x<n;x++) {
00921       if (fds[x] > -1) {
00922          pfds[y].fd = fds[x];
00923          pfds[y].events = POLLIN | POLLPRI;
00924          y++;
00925       }
00926    }
00927    res = poll(pfds, y, *ms);
00928    if (res < 0) {
00929       /* Simulate a timeout if we were interrupted */
00930       if (errno != EINTR)
00931          *ms = -1;
00932       else
00933          *ms = 0;
00934       return -1;
00935    }
00936    spoint = 0;
00937    for (x=0;x<n;x++) {
00938       if (fds[x] > -1) {
00939          if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
00940             winner = fds[x];
00941             if (exception) {
00942                if (res & POLLPRI)
00943                   *exception = -1;
00944                else
00945                   *exception = 0;
00946             }
00947          }
00948       }
00949    }
00950    if (*ms > 0) {
00951       long passed;
00952       gettimeofday(&now, NULL);
00953       passed = (now.tv_sec - start.tv_sec) * 1000;
00954       passed += (now.tv_usec - start.tv_usec) / 1000;
00955       if (passed <= *ms)
00956          *ms -= passed;
00957       else
00958          *ms = 0;
00959    }
00960    return winner;
00961 }
00962 
00963 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, 
00964    int *exception, int *outfd, int *ms)
00965 {
00966    /* Wait for x amount of time on a file descriptor to have input.  */
00967    struct timeval start, end;
00968    struct pollfd *pfds;
00969    int res;
00970    long rms;
00971    int x, y, max;
00972    int spoint;
00973    time_t now = 0;
00974    long whentohangup = 0, havewhen = 0, diff;
00975    struct ast_channel *winner = NULL;
00976 
00977    pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
00978    if (!pfds) {
00979       ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
00980       *outfd = -1;
00981       return NULL;
00982    }
00983 
00984    if (outfd)
00985       *outfd = -99999;
00986    if (exception)
00987       *exception = 0;
00988    
00989    /* Perform any pending masquerades */
00990    for (x=0;x<n;x++) {
00991       ast_mutex_lock(&c[x]->lock);
00992       if (c[x]->whentohangup) {
00993          if (!havewhen)
00994             time(&now);
00995          diff = c[x]->whentohangup - now;
00996          if (!havewhen || (diff < whentohangup)) {
00997             havewhen++;
00998             whentohangup = diff;
00999          }
01000       }
01001       if (c[x]->masq) {
01002          if (ast_do_masquerade(c[x])) {
01003             ast_log(LOG_WARNING, "Masquerade failed\n");
01004             *ms = -1;
01005             ast_mutex_unlock(&c[x]->lock);
01006             return NULL;
01007          }
01008       }
01009       ast_mutex_unlock(&c[x]->lock);
01010    }
01011 
01012    rms = *ms;
01013    
01014    if (havewhen) {
01015       if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
01016          rms =  whentohangup * 1000;
01017       }
01018    }
01019    max = 0;
01020    for (x=0;x<n;x++) {
01021       for (y=0;y<AST_MAX_FDS;y++) {
01022          if (c[x]->fds[y] > -1) {
01023             pfds[max].fd = c[x]->fds[y];
01024             pfds[max].events = POLLIN | POLLPRI;
01025             max++;
01026          }
01027       }
01028       CHECK_BLOCKING(c[x]);
01029    }
01030    for (x=0;x<nfds; x++) {
01031       if (fds[x] > -1) {
01032          pfds[max].fd = fds[x];
01033          pfds[max].events = POLLIN | POLLPRI;
01034          max++;
01035       }
01036    }
01037    if (*ms > 0) 
01038       gettimeofday(&start, NULL);
01039    res = poll(pfds, max, rms);
01040    if (res < 0) {
01041       for (x=0;x<n;x++) 
01042          c[x]->blocking = 0;
01043       /* Simulate a timeout if we were interrupted */
01044       if (errno != EINTR)
01045          *ms = -1;
01046       else {
01047          /* Just an interrupt */
01048 #if 0
01049          *ms = 0;
01050 #endif         
01051       }
01052       return NULL;
01053    }
01054 
01055    if (havewhen)
01056       time(&now);
01057    spoint = 0;
01058    for (x=0;x<n;x++) {
01059       c[x]->blocking = 0;
01060       if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
01061          c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01062          if (!winner)
01063             winner = c[x];
01064       }
01065       for (y=0;y<AST_MAX_FDS;y++) {
01066          if (c[x]->fds[y] > -1) {
01067             if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
01068                if (res & POLLPRI)
01069                   c[x]->exception = -1;
01070                else
01071                   c[x]->exception = 0;
01072                c[x]->fdno = y;
01073                winner = c[x];
01074             }
01075          }
01076       }
01077    }
01078    for (x=0;x<nfds;x++) {
01079       if (fds[x] > -1) {
01080          if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
01081             if (outfd)
01082                *outfd = fds[x];
01083             if (exception) {  
01084                if (res & POLLPRI) 
01085                   *exception = -1;
01086                else
01087                   *exception = 0;
01088             }
01089             winner = NULL;
01090          }
01091       }  
01092    }
01093    if (*ms > 0) {
01094       long diff;
01095       gettimeofday(&end, NULL);
01096       diff = (end.tv_sec - start.tv_sec) * 1000;
01097       diff += (end.tv_usec - start.tv_usec) / 1000;
01098       if (diff < *ms)
01099          *ms -= diff;
01100       else
01101          *ms = 0;
01102    }
01103    return winner;
01104 }
01105 
01106 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
01107 {
01108    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01109 }
01110 
01111 int ast_waitfor(struct ast_channel *c, int ms)
01112 {
01113    struct ast_channel *chan;
01114    int oldms = ms;
01115    chan = ast_waitfor_n(&c, 1, &ms);
01116    if (ms < 0) {
01117       if (oldms < 0)
01118          return 0;
01119       else
01120          return -1;
01121    }
01122    return ms;
01123 }
01124 
01125 char ast_waitfordigit(struct ast_channel *c, int ms)
01126 {
01127    /* XXX Should I be merged with waitfordigit_full XXX */
01128    struct ast_frame *f;
01129    char result = 0;
01130    /* Stop if we're a zombie or need a soft hangup */
01131    if (c->zombie || ast_check_hangup(c)) 
01132       return -1;
01133    /* Wait for a digit, no more than ms milliseconds total. */
01134    while(ms && !result) {
01135       ms = ast_waitfor(c, ms);
01136       if (ms < 0) /* Error */
01137          result = -1; 
01138       else if (ms > 0) {
01139          /* Read something */
01140          f = ast_read(c);
01141          if (f) {
01142             if (f->frametype == AST_FRAME_DTMF) 
01143                result = f->subclass;
01144             ast_frfree(f);
01145          } else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int outfd;
01174    int res;
01175    /* Stop if we're a zombie or need a soft hangup */
01176    if (c->zombie || ast_check_hangup(c)) 
01177       return -1;
01178    /* Wait for a digit, no more than ms milliseconds total. */
01179    while(ms) {
01180       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01181       if ((!rchan) && (outfd < 0) && (ms)) { 
01182          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01183          return -1;
01184       } else if (outfd > -1) {
01185          /* The FD we were watching has something waiting */
01186          return 1;
01187       } else if (rchan) {
01188          f = ast_read(c);
01189          if(!f) {
01190             return -1;
01191          }
01192 
01193          switch(f->frametype) {
01194          case AST_FRAME_DTMF:
01195             res = f->subclass;
01196             ast_frfree(f);
01197             return res;
01198          case AST_FRAME_CONTROL:
01199             switch(f->subclass) {
01200             case AST_CONTROL_HANGUP:
01201                ast_frfree(f);
01202                return -1;
01203             case AST_CONTROL_RINGING:
01204             case AST_CONTROL_ANSWER:
01205                /* Unimportant */
01206                break;
01207             default:
01208                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01209             }
01210          case AST_FRAME_VOICE:
01211             /* Write audio if appropriate */
01212             if (audiofd > -1)
01213                write(audiofd, f->data, f->datalen);
01214          }
01215          /* Ignore */
01216          ast_frfree(f);
01217       }
01218    }
01219    return 0; // Time is up
01220 }
01221 
01222 struct ast_frame *ast_read(struct ast_channel *chan)
01223 {
01224    struct ast_frame *f = NULL;
01225    int blah;
01226 #ifdef ZAPTEL_OPTIMIZATIONS
01227    int (*func)(void *);
01228    void *data;
01229    int res;
01230 #endif
01231    static struct ast_frame null_frame = 
01232    {
01233       AST_FRAME_NULL,
01234    };
01235    
01236    ast_mutex_lock(&chan->lock);
01237    if (chan->masq) {
01238       if (ast_do_masquerade(chan)) {
01239          ast_log(LOG_WARNING, "Failed to nlow">else
01146             result = -1;
01147       }
01148    }
01149    return result;
01150 }
01151 
01152 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01153 {
01154    int res = -1;
01155 #ifdef ZAPTEL_OPTIMIZATIONS
01156    if (c->timingfd > -1) {
01157       if (!func) {
01158          samples = 0;
01159          data = 0;
01160       }
01161       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01162       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01163       c->timingfunc = func;
01164       c->timingdata = data;
01165    }
01166 #endif   
01167    return res;
01168 }
01169 char ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01170 {
01171    struct ast_frame *f;
01172    struct ast_channel *rchan;
01173    int