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 #ifdef ZAPTEL_OPTIMIZATIONS
00042 #include <sys/ioctl.h>
00043 #ifdef __linux__
00044 #include "/usr/src/modules/zaptel/zaptel.h"
00045 #else
00046 #include <zaptel.h>
00047 #endif /* __linux__ */
00048 #ifndef ZT_TIMERPING
00049 #error "You need newer zaptel!  Please cvs update zaptel"
00050 #endif
00051 #endif
00052 
00053 /* uncomment if you have problems with 'monitoring' synchronized files */
00054 #if 0
00055 #define MONITOR_CONSTANT_DELAY
00056 #define MONITOR_DELAY   150 * 8     /* 150 ms of MONITORING DELAY */
00057 #endif
00058 
00059 static int shutting_down = 0;
00060 static int uniqueint = 0;
00061 
00062 /* XXX Lock appropriately in more functions XXX */
00063 
00064 struct chanlist {
00065    char type[80];
00066    char description[80];
00067    int capabilities;
00068    struct ast_channel * (*requester)(char *type, int format, void *data);
00069    int (*devicestate)(void *data);
00070    struct chanlist *next;
00071 } *backends = NULL;
00072 struct ast_channel *channels = NULL;
00073 
00074 /* Protect the channel list (highly unlikely that two things would change
00075    it at the same time, but still! */
00076    
00077 AST_MUTEX_DEFINE_STATIC(chlock);
00078 
00079 int ast_check_hangup(struct ast_channel *chan)
00080 {
00081 time_t   myt;
00082 
00083      /* if soft hangup flag, return true */
00084    if (chan->_softhangup) return 1;
00085      /* if no private structure, return true */
00086    if (!chan->pvt->pvt) return 1;
00087      /* if no hangup scheduled, just return here */
00088    if (!chan->whentohangup) return 0;
00089    time(&myt); /* get current time */
00090      /* return, if not yet */
00091    if (chan->whentohangup > myt) return 0;
00092    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
00093    return 1;
00094 }
00095 
00096 static int ast_check_hangup_locked(struct ast_channel *chan)
00097 {
00098    int res;
00099    ast_mutex_lock(&chan->lock);
00100    res = ast_check_hangup(chan);
00101    ast_mutex_unlock(&chan->lock);
00102    return res;
00103 }
00104 
00105 void ast_begin_shutdown(int hangup)
00106 {
00107    struct ast_channel *c;
00108    shutting_down = 1;
00109    if (hangup) {
00110       ast_mutex_lock(&chlock);
00111       c = channels;
00112       while(c) {
00113          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00114          c = c->next;
00115       }
00116       ast_mutex_unlock(&chlock);
00117    }
00118 }
00119 
00120 int ast_active_channels(void)
00121 {
00122    struct ast_channel *c;
00123    int cnt = 0;
00124    ast_mutex_lock(&chlock);
00125    c = channels;
00126    while(c) {
00127       cnt++;
00128       c = c->next;
00129    }
00130    ast_mutex_unlock(&chlock);
00131    return cnt;
00132 }
00133 
00134 void ast_cancel_shutdown(void)
00135 {
00136    shutting_down = 0;
00137 }
00138 
00139 int ast_shutting_down(void)
00140 {
00141    return shutting_down;
00142 }
00143 
00144 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00145 {
00146    time_t   myt;
00147 
00148    time(&myt);
00149    if (offset)
00150       chan->whentohangup = myt + offset;
00151    else
00152       chan->whentohangup = 0;
00153    return;
00154 }
00155 
00156 int ast_channel_register(char *type, char *description, int capabilities,
00157       struct ast_channel *(*requester)(char *type, int format, void *data))
00158 {
00159    return ast_channel_register_ex(type, description, capabilities, requester, NULL);
00160 }
00161 
00162 int ast_channel_register_ex(char *type, char *description, int capabilities,
00163       struct ast_channel *(*requester)(char *type, int format, void *data),
00164       int (*devicestate)(void *data))
00165 {
00166    struct chanlist *chan, *last=NULL;
00167    if (ast_mutex_lock(&chlock)) {
00168       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00169       return -1;
00170    }
00171    chan = backends;
00172    while (chan) {
00173       if (!strcasecmp(type, chan->type)) {
00174          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", type);
00175          ast_mutex_unlock(&chlock);
00176          return -1;
00177       }
00178       last = chan;
00179       chan = chan->next;
00180    }
00181    chan = malloc(sizeof(struct chanlist));
00182    if (!chan) {
00183       ast_log(LOG_WARNING, "Out of memory\n");
00184       ast_mutex_unlock(&chlock);
00185       return -1;
00186    }
00187    strncpy(chan->type, type, sizeof(chan->type)-1);
00188    strncpy(chan->description, description, sizeof(chan->description)-1);
00189    chan->capabilities = capabilities;
00190    chan->requester = requester;
00191    chan->devicestate = devicestate;
00192    chan->next = NULL;
00193    if (last)
00194       last->next = chan;
00195    else
00196       backends = chan;
00197    if (option_debug)
00198       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->type, chan->description);
00199    else if (option_verbose > 1)
00200       ast_verbose( VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->type, chan->description);
00201    ast_mutex_unlock(&chlock);
00202    return 0;
00203 }
00204 
00205 char *ast_state2str(int state)
00206 {
00207    /* XXX Not reentrant XXX */
00208    static char localtmp[256];
00209    switch(state) {
00210    case AST_STATE_DOWN:
00211       return "Down";
00212    case AST_STATE_RESERVED:
00213       return "Rsrvd";
00214    case AST_STATE_OFFHOOK:
00215       return "OffHook";
00216    case AST_STATE_DIALING:
00217       return "Dialing";
00218    case AST_STATE_RING:
00219       return "Ring";
00220    case AST_STATE_RINGING:
00221       return "Ringing";
00222    case AST_STATE_UP:
00223       return "Up";
00224    case AST_STATE_BUSY:
00225       return "Busy";
00226    default:
00227       snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
00228       return localtmp;
00229    }
00230 }
00231 
00232 
00233 int ast_best_codec(int fmts)
00234 {
00235    /* This just our opinion, expressed in code.  We are asked to choose
00236       the best codec to use, given no information */
00237    int x;
00238    static int prefs[] = 
00239    {
00240       /* Okay, ulaw is used by all telephony equipment, so start with it */
00241       AST_FORMAT_ULAW,
00242       /* Unless of course, you're a silly European, so then prefer ALAW */
00243       AST_FORMAT_ALAW,
00244       /* Okay, well, signed linear is easy to translate into other stuff */
00245       AST_FORMAT_SLINEAR,
00246       /* G.726 is standard ADPCM */
00247       AST_FORMAT_G726,
00248       /* ADPCM has great sound quality and is still pretty easy to translate */
00249       AST_FORMAT_ADPCM,
00250       /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00251          translate and sounds pretty good */
00252       AST_FORMAT_GSM,
00253       /* iLBC is not too bad */
00254       AST_FORMAT_ILBC,
00255       /* Speex is free, but computationally more expensive than GSM */
00256       AST_FORMAT_SPEEX,
00257       /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00258          to use it */
00259       AST_FORMAT_LPC10,
00260       /* G.729a is faster than 723 and slightly less expensive */
00261       AST_FORMAT_G729A,
00262       /* Down to G.723.1 which is proprietary but at least designed for voice */
00263       AST_FORMAT_G723_1,
00264    };
00265    
00266    
00267    for (x=0;x<sizeof(prefs) / sizeof(prefs[0]); x++)
00268       if (fmts & prefs[x])
00269          return prefs[x];
00270    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00271    return 0;
00272 }
00273 
00274 struct ast_channel *ast_channel_alloc(int needqueue)
00275 {
00276    struct ast_channel *tmp;
00277    struct ast_channel_pvt *pvt;
00278    int x;
00279    int flags;
00280    struct varshead *headp;        
00281            
00282    
00283    /* If shutting down, don't allocate any new channels */
00284    if (shutting_down)
00285       return NULL;
00286    ast_mutex_lock(&chlock);
00287    tmp = malloc(sizeof(struct ast_channel));
00288    if (tmp) {
00289       memset(tmp, 0, sizeof(struct ast_channel));
00290       pvt = malloc(sizeof(struct ast_channel_pvt));
00291       if (pvt) {
00292          memset(pvt, 0, sizeof(struct ast_channel_pvt));
00293          tmp->sched = sched_context_create();
00294          if (tmp->sched) {
00295             for (x=0;x<AST_MAX_FDS - 1;x++)
00296                tmp->fds[x] = -1;
00297 #ifdef ZAPTEL_OPTIMIZATIONS
00298             tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00299             if (tmp->timingfd > -1) {
00300                /* Check if timing interface supports new
00301                   ping/pong scheme */
00302                flags = 1;
00303                if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00304                   needqueue = 0;
00305             }
00306 #else
00307             tmp->timingfd = -1;              
00308 #endif               
00309             if (needqueue &&  
00310                pipe(pvt->alertpipe)) {
00311                ast_log(LOG_WARNING, "Alert pipe creation failed!\n");
00312                free(pvt);
00313                free(tmp);
00314                tmp = NULL;
00315                pvt = NULL;
00316             } else {
00317                if (needqueue) {
00318                   flags = fcntl(pvt->alertpipe[0], F_GETFL);
00319                   fcntl(pvt->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00320                   flags = fcntl(pvt->alertpipe[1], F_GETFL);
00321                   fcntl(pvt->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00322                } else 
00323                /* Make sure we've got it done right if they don't */
00324                   pvt->alertpipe[0] = pvt->alertpipe[1] = -1;
00325                /* Always watch the alertpipe */
00326                tmp->fds[AST_MAX_FDS-1] = pvt->alertpipe[0];
00327                /* And timing pipe */
00328                tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
00329                strncpy(tmp->name, "**Unknown**", sizeof(tmp->name)-1);
00330                tmp->pvt = pvt;
00331                /* Initial state */
00332                tmp->_state = AST_STATE_DOWN;
00333                tmp->stack = -1;
00334                tmp->streamid = -1;
00335                tmp->appl = NULL;
00336                tmp->data = NULL;
00337                tmp->fin = 0;
00338                tmp->fout = 0;
00339                snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long)time(NULL), uniqueint++);
00340                headp=&tmp->varshead;
00341                ast_mutex_init(&tmp->lock);
00342                     AST_LIST_HEAD_INIT(headp);
00343                tmp->vars=ast_var_assign("tempvar","tempval");
00344                AST_LIST_INSERT_HEAD(headp,tmp->vars,entries);
00345                strncpy(tmp->context, "default", sizeof(tmp->context)-1);
00346                strncpy(tmp->language, defaultlanguage, sizeof(tmp->language)-1);
00347                strncpy(tmp->exten, "s", sizeof(tmp->exten)-1);
00348                tmp->priority=1;
00349                tmp->amaflags = ast_default_amaflags;
00350                strncpy(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode)-1);
00351                tmp->next = channels;
00352                channels= tmp;
00353             }
00354          } else {
00355             ast_log(LOG_WARNING, "Unable to create schedule context\n");
00356             free(tmp);
00357             tmp = NULL;
00358          }
00359       } else {
00360          ast_log(LOG_WARNING, "Out of memory\n");
00361          free(tmp);
00362          tmp = NULL;
00363       }
00364    } else 
00365       ast_log(LOG_WARNING, "Out of memory\n");
00366    ast_mutex_unlock(&chlock);
00367    return tmp;
00368 }
00369 
00370 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
00371 {
00372    struct ast_frame *f;
00373    struct ast_frame *prev, *cur;
00374    int blah = 1;
00375    int qlen = 0;
00376    /* Build us a copy and free the original one */
00377    f = ast_frdup(fin);
00378    if (!f) {
00379       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00380       return -1;
00381    }
00382    ast_mutex_lock(&chan->lock);
00383    prev = NULL;
00384    cur = chan->pvt->readq;
00385    while(cur) {
00386       if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00387          /* Don't bother actually queueing anything after a hangup */
00388          ast_frfree(f);
00389          ast_mutex_unlock(&chan->lock);
00390          return 0;
00391       }
00392       prev = cur;
00393       cur = cur->next;
00394       qlen++;
00395    }
00396    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00397    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
00398       if (fin->frametype != AST_FRAME_VOICE) {
00399          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00400          CRASH;
00401       } else {
00402          ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00403          ast_frfree(f);
00404          ast_mutex_unlock(&chan->lock);
00405          return 0;
00406       }
00407    }
00408    if (prev)
00409       prev->next = f;
00410    else
00411       chan->pvt->readq = f;
00412    if (chan->pvt->alertpipe[1] > -1) {
00413       if (write(chan->pvt->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00414          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00415             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00416 #ifdef ZAPTEL_OPTIMIZATIONS
00417    } else if (chan->timingfd > -1) {
00418       ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00419 #endif            
00420    } else if (chan->blocking) {
00421       pthread_kill(chan->blocker, SIGURG);
00422    }
00423    ast_mutex_unlock(&chan->lock);
00424    return 0;
00425 }
00426 
00427 int ast_queue_hangup(struct ast_channel *chan)
00428 {
00429    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00430    chan->_softhangup |= AST_SOFTHANGUP_DEV;
00431    return ast_queue_frame(chan, &f);
00432 }
00433 
00434 int ast_queue_control(struct ast_channel *chan, int control)
00435 {
00436    struct ast_frame f = { AST_FRAME_CONTROL, };
00437    f.subclass = control;
00438    return ast_queue_frame(chan, &f);
00439 }
00440 
00441 int ast_channel_defer_dtmf(struct ast_channel *chan)
00442 {
00443    int pre = 0;
00444    if (chan) {
00445       pre = chan->deferdtmf;
00446       chan->deferdtmf = 1;
00447    }
00448    return pre;
00449 }
00450 
00451 void ast_channel_undefer_dtmf(struct ast_channel *chan)
00452 {
00453    if (chan)
00454       chan->deferdtmf = 0;
00455 }
00456 
00457 struct ast_channel *ast_channel_walk_locked(struct ast_channel *prev)
00458 {
00459    /* Returns next channel (locked) */
00460    struct ast_channel *l, *ret;
00461    int retries = 0;  
00462 retry:
00463    ret=NULL;
00464    ast_mutex_lock(&chlock);
00465    l = channels;
00466    if (!prev) {
00467       if (l) {
00468          if (ast_mutex_trylock(&l->lock)) {
00469             if (retries < 10)
00470                ast_log(LOG_DEBUG, "Avoiding initial deadlock for '%s'\n", l->name);
00471             else
00472                ast_log(LOG_WARNING, "Avoided initial deadlock for '%s', %d retries!\n", l->name, retries);
00473             ast_mutex_unlock(&chlock);
00474             if (retries < 10) {
00475                usleep(1);
00476                retries++;
00477                goto retry;
00478             } else
00479                return NULL;
00480          }
00481       }
00482       ast_mutex_unlock(&chlock);
00483       return l;
00484    }
00485    while(l) {
00486       if (l == prev)
00487          ret = l->next;
00488       l = l->next;
00489    }
00490    if (ret) {
00491       if (ast_mutex_trylock(&ret->lock)) {
00492          if (retries < 10)
00493             ast_log(LOG_DEBUG, "Avoiding deadlock for '%s'\n", ret->name);
00494          else
00495             ast_log(LOG_WARNING, "Avoided deadlock for '%s', %d retries!\n", ret->name, retries);
00496          ast_mutex_unlock(&chlock);
00497          if (retries < 10) {
00498             usleep(1);
00499             retries++;
00500             goto retry;
00501          } else
00502             return NULL;
00503       }
00504    }
00505    ast_mutex_unlock(&chlock);
00506    return ret;
00507    
00508 }
00509 
00510 struct ast_channel *ast_get_channel_by_name_locked(char *channame)
00511 {
00512    struct ast_channel *chan;
00513    chan = ast_channel_walk_locked(NULL);
00514    while(chan) {
00515       if (!strcasecmp(chan->name, channame))
00516          return chan;
00517       ast_mutex_unlock(&chan->lock);
00518       chan = ast_channel_walk_locked(chan);
00519    }
00520    return NULL;
00521 }
00522 
00523 int ast_safe_sleep_conditional(  struct ast_channel *chan, int ms,
00524                         int (*cond)(void*), void *data )
00525 {
00526    struct ast_frame *f;
00527 
00528    while(ms > 0) {
00529       if( cond && ((*cond)(data) == 0 ) )
00530          return 0;
00531       ms = ast_waitfor(chan, ms);
00532       if (ms <0)
00533          return -1;
00534       if (ms > 0) {
00535          f = ast_read(chan);
00536          if (!f)
00537             return -1;
00538          ast_frfree(f);
00539       }
00540    }
00541    return 0;
00542 }
00543 
00544 int ast_safe_sleep(struct ast_channel *chan, int ms)
00545 {
00546    struct ast_frame *f;
00547    while(ms > 0) {
00548       ms = ast_waitfor(chan, ms);
00549       if (ms <0)
00550          return -1;
00551       if (ms > 0) {
00552          f = ast_read(chan);
00553          if (!f)
00554             return -1;
00555          ast_frfree(f);
00556       }
00557    }
00558    return 0;
00559 }
00560 
00561 void ast_channel_free(struct ast_channel *chan)
00562 {
00563    struct ast_channel *last=NULL, *cur;
00564    int fd;
00565    struct ast_var_t *vardata;
00566    struct ast_frame *f, *fp;
00567    struct varshead *headp;
00568    char name[AST_CHANNEL_NAME];
00569    
00570    headp=&chan->varshead;
00571    
00572    ast_mutex_lock(&chlock);
00573    cur = channels;
00574    while(cur) {
00575       if (cur == chan) {
00576          if (last)
00577             last->next = cur->next;
00578          else
00579             channels = cur->next;
00580          break;
00581       }
00582       last = cur;
00583       cur = cur->next;
00584    }
00585    if (!cur)
00586       ast_log(LOG_WARNING, "Unable to find channel in list\n");
00587    else {
00588       /* Lock and unlock the channel just to be sure nobody
00589          has it locked still */
00590       ast_mutex_lock(&cur->lock);
00591       ast_mutex_unlock(&cur->lock);
00592    }
00593    if (chan->pvt->pvt)
00594       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
00595 
00596    strncpy(name, chan->name, sizeof(name)-1);
00597    
00598    /* Stop monitoring */
00599    if (chan->monitor) {
00600       chan->monitor->stop( chan, 0 );
00601    }
00602 
00603    /* Free translatosr */
00604    if (chan->pvt->readtrans)
00605       ast_translator_free_path(chan->pvt->readtrans);
00606    if (chan->pvt->writetrans)
00607       ast_translator_free_path(chan->pvt->writetrans);
00608    if (chan->pbx) 
00609       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
00610    if (chan->dnid)
00611       free(chan->dnid);
00612    if (chan->callerid)
00613       free(chan->callerid);   
00614    if (chan->ani)
00615       free(chan->ani);
00616    if (chan->rdnis)
00617       free(chan->rdnis);
00618    ast_mutex_destroy(&chan->lock);
00619    /* Close pipes if appropriate */
00620    if ((fd = chan->pvt->alertpipe[0]) > -1)
00621       close(fd);
00622    if ((fd = chan->pvt->alertpipe[1]) > -1)
00623       close(fd);
00624    if ((fd = chan->timingfd) > -1)
00625       close(fd);
00626    f = chan->pvt->readq;
00627    chan->pvt->readq = NULL;
00628    while(f) {
00629       fp = f;
00630       f = f->next;
00631       ast_frfree(fp);
00632    }
00633    
00634    /* loop over the variables list, freeing all data and deleting list items */
00635    /* no need to lock the list, as the channel is already locked */
00636    
00637    while (!AST_LIST_EMPTY(headp)) {           /* List Deletion. */
00638                vardata = AST_LIST_FIRST(headp);
00639                AST_LIST_REMOVE_HEAD(headp, entries);
00640 //             printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata));
00641                ast_var_delete(vardata);
00642    }
00643                                                     
00644 
00645    free(chan->pvt);
00646    chan->pvt = NULL;
00647    free(chan);
00648    ast_mutex_unlock(&chlock);
00649 
00650    ast_device_state_changed(name);
00651 }
00652 
00653 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
00654 {
00655    int res = 0;
00656    struct ast_frame f = { AST_FRAME_NULL };
00657    if (option_debug)
00658       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
00659    /* Inform channel driver that we need to be hung up, if it cares */
00660    chan->_softhangup |= cause;
00661    ast_queue_frame(chan, &f);
00662    /* Interrupt any poll call or such */
00663    if (chan->blocking)
00664       pthread_kill(chan->blocker, SIGURG);
00665    return res;
00666 }
00667 
00668 int ast_softhangup(struct ast_channel *chan, int cause)
00669 {
00670    int res;
00671    ast_mutex_lock(&chan->lock);
00672    res = ast_softhangup_nolock(chan, cause);
00673    ast_mutex_unlock(&chan->lock);
00674    return res;
00675 }
00676 
00677 static void free_translation(struct ast_channel *clone)
00678 {
00679    if (clone->pvt->writetrans)
00680       ast_translator_free_path(clone->pvt->writetrans);
00681    if (clone->pvt->readtrans)
00682       ast_translator_free_path(clone->pvt->readtrans);
00683    clone->pvt->writetrans = NULL;
00684    clone->pvt->readtrans = NULL;
00685    clone->pvt->rawwriteformat = clone->nativeformats;
00686    clone->pvt->rawreadformat = clone->nativeformats;
00687 }
00688 
00689 int ast_hangup(struct ast_channel *chan)
00690 {
00691    int res = 0;
00692    /* Don't actually hang up a channel that will masquerade as someone else, or
00693       if someone is going to masquerade as us */
00694    ast_mutex_lock(&chan->lock);
00695    if (chan->masq) {
00696       if (ast_do_masquerade(chan)) 
00697          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
00698    }
00699 
00700    if (chan->masq) {
00701       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
00702       ast_mutex_unlock(&chan->lock);
00703       return 0;
00704    }
00705    /* If this channel is one which will be masqueraded into something, 
00706       mark it as a zombie already, so we know to free it later */
00707    if (chan->masqr) {
00708       chan->zombie=1;
00709       ast_mutex_unlock(&chan->lock);
00710       return 0;
00711    }
00712    free_translation(chan);
00713    if (chan->stream) 
00714       ast_closestream(chan->stream);
00715    if (chan->vstream)
00716       ast_closestream(chan->vstream);
00717    if (chan->sched)
00718       sched_context_destroy(chan->sched);
00719    /* Clear any tone stuff remaining */
00720    if (chan->generatordata)
00721       chan->generator->release(chan, chan->generatordata);
00722    chan->generatordata = NULL;
00723    chan->generator = NULL;
00724    if (chan->cdr) {
00725       /* End the CDR if it hasn't already */
00726       ast_cdr_end(chan->cdr);
00727       /* Post and Free the CDR */
00728       ast_cdr_post(chan->cdr);
00729       ast_cdr_free(chan->cdr);
00730    }
00731    if (chan->blocking) {
00732       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
00733                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
00734                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
00735       CRASH;
00736    }
00737    if (!chan->zombie) {
00738       if (option_debug)
00739          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
00740       if (chan->pvt->hangup)
00741          res = chan->pvt->hangup(chan);
00742    } else
00743       if (option_debug)
00744          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
00745          
00746    ast_mutex_unlock(&chan->lock);
00747    manager_event(EVENT_FLAG_CALL, "Hangup", 
00748          "Channel: %s\r\n"
00749          "Uniqueid: %s\r\n"
00750          "Cause: %i\r\n",
00751          chan->name, chan->uniqueid, chan->hangupcause);
00752    ast_channel_free(chan);
00753    return res;
00754 }
00755 
00756 void ast_channel_unregister(char *type)
00757 {
00758    struct chanlist *chan, *last=NULL;
00759    if (option_debug)
00760       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", type);
00761    if (ast_mutex_lock(&chlock)) {
00762       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00763       return;
00764    }
00765    if (option_verbose > 1)
00766       ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", type);
00767 
00768    chan = backends;
00769    while(chan) {
00770       if (!strcasecmp(chan->type, type)) {
00771          if (last)
00772             last->next = chan->next;
00773          else
00774             backends = backends->next;
00775          free(chan);
00776          ast_mutex_unlock(&chlock);
00777          return;
00778       }
00779       last = chan;
00780       chan = chan->next;
00781    }
00782    ast_mutex_unlock(&chlock);
00783 }
00784 
00785 int ast_answer(struct ast_channel *chan)
00786 {
00787    int res = 0;
00788    ast_mutex_lock(&chan->lock);
00789    /* Stop if we're a zombie or need a soft hangup */
00790    if (chan->zombie || ast_check_hangup(chan)) {
00791       ast_mutex_unlock(&chan->lock);
00792       return -1;
00793    }
00794    switch(chan->_state) {
00795    case AST_STATE_RINGING:
00796    case AST_STATE_RING:
00797       if (chan->pvt->answer)
00798          res = chan->pvt->answer(chan);
00799       ast_setstate(chan, AST_STATE_UP);
00800       if (chan->cdr)
00801          ast_cdr_answer(chan->cdr);
00802       ast_mutex_unlock(&chan->lock);
00803       return res;
00804       break;
00805    case AST_STATE_UP:
00806       if (chan->cdr)
00807          ast_cdr_answer(chan->cdr);
00808       break;
00809    }
00810    ast_mutex_unlock(&chan->lock);
00811    return 0;
00812 }
00813 
00814 
00815 
00816 void ast_deactivate_generator(struct ast_channel *chan)
00817 {
00818    ast_mutex_lock(&chan->lock);
00819    if (chan->generatordata) {
00820       if (chan->generator && chan->generator->release) 
00821          chan->generator->release(chan, chan->generatordata);
00822       chan->generatordata = NULL;
00823       chan->generator = NULL;
00824       chan->writeinterrupt = 0;
00825       ast_settimeout(chan, 0, NULL, NULL);
00826    }
00827    ast_mutex_unlock(&chan->lock);
00828 }
00829 
00830 static int generator_force(void *data)
00831 {
00832    /* Called if generator doesn't have data */
00833    void *tmp;
00834    int res;
00835    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
00836    struct ast_channel *chan = data;
00837    tmp = chan->generatordata;
00838    chan->generatordata = NULL;
00839    generate = chan->generator->generate;
00840    res = generate(chan, tmp, 0, 160);
00841    chan->generatordata = tmp;
00842    if (res) {
00843       ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
00844       ast_deactivate_generator(chan);
00845    }
00846    return 0;
00847 }
00848 
00849 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
00850 {
00851    int res = 0;
00852    ast_mutex_lock(&chan->lock);
00853    if (chan->generatordata) {
00854       if (chan->generator && chan->generator->release)
00855          chan->generator->release(chan, chan->generatordata);
00856       chan->generatordata = NULL;
00857    }
00858    ast_prod(chan);
00859    if ((chan->generatordata = gen->alloc(chan, params))) {
00860       ast_settimeout(chan, 160, generator_force, chan);
00861       chan->generator = gen;
00862    } else {
00863       res = -1;
00864    }
00865    ast_mutex_unlock(&chan->lock);
00866    return res;
00867 }
00868 
00869 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
00870 {
00871    /* Wait for x amount of time on a file descriptor to have input.  */
00872    struct timeval start, now;
00873    int res;
00874    int x, y;
00875    int winner = -1;
00876    int spoint;
00877    struct pollfd *pfds;
00878    
00879    pfds = alloca(sizeof(struct pollfd) * n);
00880    if (!pfds) {
00881       ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
00882       return -1;
00883    }
00884    if (*ms > 0)
00885       gettimeofday(&start, NULL);
00886    y = 0;
00887    for (x=0;x<n;x++) {
00888       if (fds[x] > -1) {
00889          pfds[y].fd = fds[x];
00890          pfds[y].events = POLLIN | POLLPRI;
00891          y++;
00892       }
00893    }
00894    res = poll(pfds, y, *ms);
00895    if (res < 0) {
00896       /* Simulate a timeout if we were interrupted */
00897       if (errno != EINTR)
00898          *ms = -1;
00899       else
00900          *ms = 0;
00901       return -1;
00902    }
00903    spoint = 0;
00904    for (x=0;x<n;x++) {
00905       if (fds[x] > -1) {
00906          if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
00907             winner = fds[x];
00908             if (exception) {
00909                if (res & POLLPRI)
00910                   *exception = -1;
00911                else
00912                   *exception = 0;
00913             }
00914          }
00915       }
00916    }
00917    if (*ms > 0) {
00918       long passed;
00919       gettimeofday(&now, NULL);
00920       passed = (now.tv_sec - start.tv_sec) * 1000;
00921       passed += (now.tv_usec - start.tv_usec) / 1000;
00922       if (passed <= *ms)
00923          *ms -= passed;
00924       else
00925          *ms = 0;
00926    }
00927    return winner;
00928 }
00929 
00930 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, 
00931    int *exception, int *outfd, int *ms)
00932 {
00933    /* Wait for x amount of time on a file descriptor to have input.  */
00934    struct timeval start, end;
00935    struct pollfd *pfds;
00936    int res;
00937    long rms;
00938    int x, y, max;
00939    int spoint;
00940    time_t now = 0;
00941    long whentohangup = 0, havewhen = 0, diff;
00942    struct ast_channel *winner = NULL;
00943 
00944    pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
00945    if (!pfds) {
00946       ast_log(LOG_WARNING, "alloca failed!  bad things will happen.\n");
00947       *outfd = -1;
00948       return NULL;
00949    }
00950 
00951    if (outfd)
00952       *outfd = -99999;
00953    if (exception)
00954       *exception = 0;
00955    
00956    /* Perform any pending masquerades */
00957    for (x=0;x<n;x++) {
00958       ast_mutex_lock(&c[x]->lock);
00959       if (c[x]->whentohangup) {
00960          if (!havewhen)
00961             time(&now);
00962          diff = c[x]->whentohangup - now;
00963          if (!havewhen || (diff < whentohangup)) {
00964             havewhen++;
00965             whentohangup = diff;
00966          }
00967       }
00968       if (c[x]->masq) {
00969          if (ast_do_masquerade(c[x])) {
00970             ast_log(LOG_WARNING, "Masquerade failed\n");
00971             *ms = -1;
00972             ast_mutex_unlock(&c[x]->lock);
00973             return NULL;
00974          }
00975       }
00976       ast_mutex_unlock(&c[x]->lock);
00977    }
00978 
00979    rms = *ms;
00980    
00981    if (havewhen) {
00982       if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
00983          rms =  whentohangup * 1000;
00984       }
00985    }
00986    max = 0;
00987    for (x=0;x<n;x++) {
00988       for (y=0;y<AST_MAX_FDS;y++) {
00989          if (c[x]->fds[y] > -1) {
00990             pfds[max].fd = c[x]->fds[y];
00991             pfds[max].events = POLLIN | POLLPRI;
00992             max++;
00993          }
00994       }
00995       CHECK_BLOCKING(c[x]);
00996    }
00997    for (x=0;x<nfds; x++) {
00998       if (fds[x] > -1) {
00999          pfds[max].fd = fds[x];
01000          pfds[max].events = POLLIN | POLLPRI;
01001          max++;
01002       }
01003    }
01004    if (*ms > 0) 
01005       gettimeofday(&start, NULL);
01006    res = poll(pfds, max, rms);
01007    if (res < 0) {
01008       for (x=0;x<n;x++) 
01009          c[x]->blocking = 0;
01010       /* Simulate a timeout if we were interrupted */
01011       if (errno != EINTR)
01012          *ms = -1;
01013       else {
01014          /* Just an interrupt */
01015 #if 0
01016          *ms = 0;
01017 #endif         
01018       }
01019       return NULL;
01020    }
01021 
01022    if (havewhen)
01023       time(&now);
01024    spoint = 0;
01025    for (x=0;x<n;x++) {
01026       c[x]->blocking = 0;
01027       if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
01028          c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01029          if (!winner)
01030             winner = c[x];
01031       }
01032       for (y=0;y<AST_MAX_FDS;y++) {
01033          if (c[x]->fds[y] > -1) {
01034             if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
01035                if (res & POLLPRI)
01036                   c[x]->exception = -1;
01037                else
01038                   c[x]->exception = 0;
01039                c[x]->fdno = y;
01040                winner = c[x];
01041             }
01042          }
01043       }
01044    }
01045    for (x=0;x<nfds;x++) {
01046       if (fds[x] > -1) {
01047          if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
01048             if (outfd)
01049                *outfd = fds[x];
01050             if (exception) {  
01051                if (res & POLLPRI) 
01052                   *exception = -1;
01053                else
01054                   *exception = 0;
01055             }
01056             winner = NULL;
01057          }
01058       }  
01059    }
01060    if (*ms > 0) {
01061       long diff;
01062       gettimeofday(&end, NULL);
01063       diff = (end.tv_sec - start.tv_sec) * 1000;
01064       diff += (end.tv_usec - start.tv_usec) / 1000;
01065       if (diff < *ms)
01066          *ms -= diff;
01067       else
01068          *ms = 0;
01069    }
01070    return winner;
01071 }
01072 
01073 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
01074 {
01075    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01076 }
01077 
01078 int ast_waitfor(struct ast_channel *c, int ms)
01079 {
01080    struct ast_channel *chan;
01081    int oldms = ms;
01082    chan = ast_waitfor_n(&c, 1, &ms);
01083    if (ms < 0) {
01084       if (oldms < 0)
01085          return 0;
01086       else
01087          return -1;
01088    }
01089    return ms;
01090 }
01091 
01092 int ast_waitfordigit(struct ast_channel *c, int ms)
01093 {
01094    /* XXX Should I be merged with waitfordigit_full XXX */
01095    struct ast_frame *f;
01096    int result = 0;
01097    /* Stop if we're a zombie or need a soft hangup */
01098    if (c->zombie || ast_check_hangup(c)) 
01099       return -1;
01100    /* Wait for a digit, no more than ms milliseconds total. */
01101    while(ms && !result) {
01102       ms = ast_waitfor(c, ms);
01103       if (ms < 0) /* Error */
01104          result = -1; 
01105       else if (ms > 0) {
01106          /* Read something */
01107          f = ast_read(c);
01108          if (f) {
01109             if (f->frametype == AST_FRAME_DTMF) 
01110                result = f->subclass;
01111             ast_frfree(f);
01112          } else
01113             result = -1;
01114       }
01115    }
01116    return result;
01117 }
01118 
01119 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
01120 {
01121    int res = -1;
01122 #ifdef ZAPTEL_OPTIMIZATIONS
01123    if (c->timingfd > -1) {
01124       if (!func) {
01125          samples = 0;
01126          data = 0;
01127       }
01128       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01129       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01130       c->timingfunc = func;
01131       c->timingdata = data;
01132    }
01133 #endif   
01134    return res;
01135 }
01136 int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
01137 {
01138    struct ast_frame *f;
01139    struct ast_channel *rchan;
01140    int outfd;
01141    int res;
01142    /* Stop if we're a zombie or need a soft hangup */
01143    if (c->zombie || ast_check_hangup(c)) 
01144       return -1;
01145    /* Wait for a digit, no more than ms milliseconds total. */
01146    while(ms) {
01147       errno = 0;
01148       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01149       if ((!rchan) && (outfd < 0) && (ms)) { 
01150          if (errno == 0 || errno == EINTR)
01151             continue;
01152          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01153          return -1;
01154       } else if (outfd > -1) {
01155          /* The FD we were watching has something waiting */
01156          return 1;
01157       } else if (rchan) {
01158          f = ast_read(c);
01159          if(!f) {
01160             return -1;
01161          }
01162 
01163          switch(f->frametype) {
01164          case AST_FRAME_DTMF:
01165             res = f->subclass;
01166             ast_frfree(f);
01167             return res;
01168          case AST_FRAME_CONTROL:
01169             switch(f->subclass) {
01170             case AST_CONTROL_HANGUP:
01171                ast_frfree(f);
01172                return -1;
01173             case AST_CONTROL_RINGING:
01174             case AST_CONTROL_ANSWER:
01175                /* Unimportant */
01176                break;
01177             default:
01178                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01179             }
01180          case AST_FRAME_VOICE:
01181             /* Write audio if appropriate */
01182             if (audiofd > -1)
01183                write(audiofd, f->data, f->datalen);
01184          }
01185          /* Ignore */
01186          ast_frfree(f);
01187       }
01188    }
01189    return 0; // Time is up
01190 }
01191 
01192 struct ast_frame *ast_read(struct ast_channel *chan)
01193 {
01194    struct ast_frame *f = NULL;
01195    int blah;
01196 #ifdef ZAPTEL_OPTIMIZATIONS
01197    int (*func)(void *);
01198    void *data;
01199    int res;
01200 #endif
01201    static struct ast_frame null_frame = 
01202    {
01203       AST_FRAME_NULL,
01204    };
01205    
01206    ast_mutex_lock(&chan->lock);
01207    if (chan->masq) {
01208       if (ast_do_masquerade(chan)) {
01209          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01210          f = NULL;
01211       } else
01212          f =  &null_frame;
01213       ast_mutex_unlock(&chan->lock);
01214       return f;
01215    }
01216 
01217    /* Stop if we're a zombie or need a soft hangup */
01218    if (chan->zombie || ast_check_hangup(chan)) {
01219       if (chan->generator)
01220          ast_deactivate_generator(chan);
01221       ast_mutex_unlock(&chan->lock);
01222       return NULL;
01223    }
01224 
01225    if (!chan->deferdtmf && !ast_strlen_zero(chan->dtmfq)) {
01226       /* We have DTMF that has been deferred.  Return it now */
01227       chan->dtmff.frametype = AST_FRAME_DTMF;
01228       chan->dtmff.subclass = chan->dtmfq[0];
01229       /* Drop first digit */
01230       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01231       ast_mutex_unlock(&chan->lock);
01232       return &chan->dtmff;
01233    }
01234    
01235    /* Read and ignore anything on the alertpipe, but read only
01236       one sizeof(blah) per frame that we send from it */
01237    if (chan->pvt->alertpipe[0] > -1) {
01238       read(chan->pvt->alertpipe[0], &blah, sizeof(blah));
01239    }
01240 #ifdef ZAPTEL_OPTIMIZATIONS
01241    if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && chan->exception) {
01242       chan->exception = 0;
01243       blah = -1;
01244       /* IF we can't get event, assume it's an expired as-per the old interface */
01245       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
01246       if (res) 
01247          blah = ZT_EVENT_TIMER_EXPIRED;
01248 
01249       if (blah == ZT_EVENT_TIMER_PING) {
01250 #if 0
01251          ast_log(LOG_NOTICE, "Oooh, there's a PING!\n");
01252 #endif         
01253          if (!chan->pvt->readq || !chan->pvt->readq->next) {
01254             /* Acknowledge PONG unless we need it again */
01255 #if 0
01256             ast_log(LOG_NOTICE, "Sending a PONG!\n");
01257 #endif            
01258             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
01259                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
01260             }
01261          }
01262       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
01263          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01264          func = chan->timingfunc;
01265          data = chan->timingdata;
01266          ast_mutex_unlock(&chan->lock);
01267          if (func) {
01268 #if 0
01269             ast_log(LOG_DEBUG, "Calling private function\n");
01270 #endif         
01271             func(data);
01272          } else {
01273             blah = 0;
01274             ast_mutex_lock(&chan->lock);
01275             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
01276             chan->timingdata = NULL;
01277             ast_mutex_unlock(&chan->lock);
01278          }
01279          f =  &null_frame;
01280          return f;
01281       } else
01282          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
01283    }
01284 #endif
01285    /* Check for pending read queue */
01286    if (chan->pvt->readq) {
01287       f = chan->pvt->readq;
01288       chan->pvt->readq = f->next;
01289       /* Interpret hangup and return NULL */
01290       if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
01291          ast_frfree(f);
01292          f = NULL;
01293       }
01294    } else {
01295       chan->blocker = pthread_self();
01296       if (chan->exception) {
01297          if (chan->pvt->exception) 
01298             f = chan->pvt->exception(chan);
01299          else {
01300             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
01301             f = &null_frame;
01302          }
01303          /* Clear the exception flag */
01304          chan->exception = 0;
01305       } else
01306       if (chan->pvt->read)
01307          f = chan->pvt->read(chan);
01308       else
01309          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
01310    }
01311 
01312 
01313    if (f && (f->frametype == AST_FRAME_VOICE)) {
01314       if (!(f->subclass & chan->nativeformats)) {
01315          /* This frame can't be from the current native formats -- drop it on the
01316             floor */
01317          ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n", chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
01318          ast_frfree(f);
01319          f = &null_frame;
01320       } else {
01321          if (chan->monitor && chan->monitor->read_stream ) {
01322 #ifndef MONITOR_CONSTANT_DELAY
01323             int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
01324             if (jump >= 0) {
01325                if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01326                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01327                chan->insmpl += jump + 2 * f->samples;
01328             } else
01329                chan->insmpl+= f->samples;
01330 #else
01331             int jump = chan->outsmpl - chan->insmpl;
01332             if (jump - MONITOR_DELAY >= 0) {
01333                if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01334                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
01335                chan->insmpl += jump;
01336             } else
01337                chan->insmpl += f->samples;
01338 #endif
01339             if (ast_writestream(chan->monitor->read_stream, f) < 0)
01340                ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
01341          }
01342          if (chan->pvt->readtrans) {
01343             f = ast_translate(chan->pvt->readtrans, f, 1);
01344             if (!f)
01345                f = &null_frame;
01346          }
01347       }
01348    }
01349 
01350    /* Make sure we always return NULL in the future */
01351    if (!f) {
01352       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01353       if (chan->generator)
01354          ast_deactivate_generator(chan);
01355       /* End the CDR if appropriate */
01356       if (chan->cdr)
01357          ast_cdr_end(chan->cdr);
01358    } else if (chan->deferdtmf && f->frametype == AST_FRAME_DTMF) {
01359       if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
01360          chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
01361       else
01362          ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
01363       f = &null_frame;
01364    } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
01365       if (chan->_state == AST_STATE_UP) {
01366          ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
01367          f = &null_frame;
01368       }
01369       /* Answer the CDR */
01370       ast_setstate(chan, AST_STATE_UP);
01371       ast_cdr_answer(chan->cdr);
01372    } 
01373 
01374    /* Run any generator sitting on the line */
01375    if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
01376       /* Mask generator data temporarily and apply.  If there is a timing function, it
01377          will be calling the generator instead */
01378       void *tmp;
01379       int res;
01380       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
01381       if (chan->timingfunc) {
01382          ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
01383          ast_settimeout(chan, 0, NULL, NULL);
01384       }
01385       tmp = chan->generatordata;
01386       chan->generatordata = NULL;
01387       generate = chan->generator->generate;
01388       res = generate(chan, tmp, f->datalen, f->samples);
01389       chan->generatordata = tmp;
01390       if (res) {
01391          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01392          ast_deactivate_generator(chan);
01393       }
01394    } else if (f && (f->frametype == AST_FRAME_CNG)) {
01395       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
01396          ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n");
01397          ast_settimeout(chan, 160, generator_force, chan);
01398       }
01399    }
01400    /* High bit prints debugging */
01401    if (chan->fin & 0x80000000)
01402       ast_frame_dump(chan->name, f, "<<");
01403    if ((chan->fin & 0x7fffffff) == 0x7fffffff)
01404       chan->fin &= 0x80000000;
01405    else
01406       chan->fin++;
01407    ast_mutex_unlock(&chan->lock);
01408    return f;
01409 }
01410 
01411 int ast_indicate(struct ast_channel *chan, int condition)
01412 {
01413    int res = -1;
01414    /* Stop if we're a zombie or need a soft hangup */
01415    if (chan->zombie || ast_check_hangup(chan)) 
01416       return -1;
01417    ast_mutex_lock(&chan->lock);
01418    if (chan->pvt->indicate)
01419       res = chan->pvt->indicate(chan, condition);
01420    ast_mutex_unlock(&chan->lock);
01421    if (!chan->pvt->indicate || res) {
01422       /*
01423        * Device does not support (that) indication, lets fake
01424        * it by doing our own tone generation. (PM2002)
01425        */
01426       if (condition >= 0) {
01427          const struct tone_zone_sound *ts = NULL;
01428          switch (condition) {
01429           case AST_CONTROL_RINGING:
01430             ts = ast_get_indication_tone(chan->zone, "ring");
01431             break;
01432           case AST_CONTROL_BUSY:
01433             ts = ast_get_indication_tone(chan->zone, "busy");
01434             break;
01435           case AST_CONTROL_CONGESTION:
01436             ts = ast_get_indication_tone(chan->zone, "congestion");
01437             break;
01438          }
01439          if (ts && ts->data[0]) {
01440             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
01441             ast_playtones_start(chan,0,ts->data, 1);
01442             res = 0;
01443          } else if (condition == AST_CONTROL_PROGRESS) {
01444             /* ast_playtones_stop(chan); */
01445          } else if (condition == AST_CONTROL_PROCEEDING) {
01446             /* Do nothing, really */
01447          } else {
01448             /* not handled */
01449             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
01450             res = -1;
01451          }
01452       }
01453       else ast_playtones_stop(chan);
01454    }
01455    return res;
01456 }
01457 
01458 int ast_recvchar(struct ast_channel *chan, int timeout)
01459 {
01460    int res,ourto,c;
01461    struct ast_frame *f;
01462    
01463    ourto = timeout;
01464    for(;;)
01465       {
01466       if (ast_check_hangup(chan)) return -1;
01467       res = ast_waitfor(chan,ourto);
01468       if (res <= 0) /* if timeout */
01469          {
01470          return 0;
01471          }
01472       ourto = res;
01473       f = ast_read(chan);
01474       if (f == NULL) return -1; /* if hangup */
01475       if ((f->frametype == AST_FRAME_CONTROL) &&
01476           (f->subclass == AST_CONTROL_HANGUP)) return -1; /* if hangup */
01477       if (f->frametype == AST_FRAME_TEXT)  /* if a text frame */
01478          {
01479          c = *((char *)f->data);  /* get the data */
01480          ast_frfree(f);
01481          return(c);
01482          }
01483       ast_frfree(f);
01484    }
01485 }
01486 
01487 int ast_sendtext(struct ast_channel *chan, char *text)
01488 {
01489    int res = 0;
01490    /* Stop if we're a zombie or need a soft hangup */
01491    if (chan->zombie || ast_check_hangup(chan)) 
01492       return -1;
01493    CHECK_BLOCKING(chan);
01494    if (chan->pvt->send_text)
01495       res = chan->pvt->send_text(chan, text);
01496    chan->blocking = 0;
01497    return res;
01498 }
01499 
01500 static int do_senddigit(struct ast_channel *chan, char digit)
01501 {
01502    int res = -1;
01503 
01504    if (chan->pvt->send_digit)
01505       res = chan->pvt->send_digit(chan, digit);
01506    if (!chan->pvt->send_digit || res) {
01507       /*
01508        * Device does not support DTMF tones, lets fake
01509        * it by doing our own generation. (PM2002)
01510        */
01511       static const char* dtmf_tones[] = {
01512          "!941+1336/100,!0/100", /* 0 */
01513          "!697+1209/100,!0/100", /* 1 */
01514          "!697+1336/100,!0/100", /* 2 */
01515          "!697+1477/100,!0/100", /* 3 */
01516          "!770+1209/100,!0/100", /* 4 */
01517          "!770+1336/100,!0/100", /* 5 */
01518          "!770+1477/100,!0/100", /* 6 */
01519          "!852+1209/100,!0/100", /* 7 */
01520          "!852+1336/100,!0/100", /* 8 */
01521          "!852+1477/100,!0/100", /* 9 */
01522          "!697+1633/100,!0/100", /* A */
01523          "!770+1633/100,!0/100", /* B */
01524          "!852+1633/100,!0/100", /* C */
01525          "!941+1633/100,!0/100", /* D */
01526          "!941+1209/100,!0/100", /* * */
01527          "!941+1477/100,!0/100" };  /* # */
01528       if (digit >= '0' && digit <='9')
01529          ast_playtones_start(chan,0,dtmf_tones[digit-'0'], 0);
01530       else if (digit >= 'A' && digit <= 'D')
01531          ast_playtones_start(chan,0,dtmf_tones[digit-'A'+10], 0);
01532       else if (digit == '*')
01533          ast_playtones_start(chan,0,dtmf_tones[14], 0);
01534       else if (digit == '#')
01535          ast_playtones_start(chan,0,dtmf_tones[15], 0);
01536       else {
01537          /* not handled */
01538          ast_log(LOG_DEBUG, "Unable to handle DTMF tone '%c' for '%s'\n", digit, chan->name);
01539       }
01540    }
01541    return 0;
01542 }
01543 
01544 int ast_senddigit(struct ast_channel *chan, char digit)
01545 {
01546    return do_senddigit(chan, digit);
01547 }
01548 
01549 int ast_prod(struct ast_channel *chan)
01550 {
01551    struct ast_frame a = { AST_FRAME_VOICE };
01552    char nothing[128];
01553    /* Send an empty audio frame to get things moving */
01554    if (chan->_state != AST_STATE_UP) {
01555       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
01556       a.subclass = chan->pvt->rawwriteformat;
01557       a.data = nothing + AST_FRIENDLY_OFFSET;
01558       if (ast_write(chan, &a))
01559          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
01560    }
01561    return 0;
01562 }
01563 
01564 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
01565 {
01566    int res;
01567    if (!chan->pvt->write_video)
01568       return 0;
01569    res = ast_write(chan, fr);
01570    if (!res)
01571       res = 1;
01572    return res;
01573 }
01574 
01575 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
01576 {
01577    int res = -1;
01578    struct ast_frame *f = NULL;
01579    /* Stop if we're a zombie or need a soft hangup */
01580    ast_mutex_lock(&chan->lock);
01581    if (chan->zombie || ast_check_hangup(chan))  {
01582       ast_mutex_unlock(&chan->lock);
01583       return -1;
01584    }
01585    /* Handle any pending masquerades */
01586    if (chan->masq) {
01587       if (ast_do_masquerade(chan)) {
01588          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01589          ast_mutex_unlock(&chan->lock);
01590          return -1;
01591       }
01592    }
01593    if (chan->masqr) {
01594       ast_mutex_unlock(&chan->lock);
01595       return 0;
01596    }
01597    if (chan->generatordata) {
01598       if (chan->writeinterrupt)
01599          ast_deactivate_generator(chan);
01600       else {
01601          ast_mutex_unlock(&chan->lock);
01602          return 0;
01603       }
01604    }
01605    /* High bit prints debugging */
01606    if (chan->fout & 0x80000000)
01607       ast_frame_dump(chan->name, fr, ">>");
01608    CHECK_BLOCKING(chan);
01609    switch(fr->frametype) {
01610    case AST_FRAME_CONTROL:
01611       /* XXX Interpret control frames XXX */
01612       ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
01613       break;
01614    case AST_FRAME_DTMF:
01615       chan->blocking = 0;
01616       ast_mutex_unlock(&chan->lock);
01617       res = do_senddigit(chan,fr->subclass);
01618       ast_mutex_lock(&chan->lock);
01619       CHECK_BLOCKING(chan);
01620       break;
01621    case AST_FRAME_TEXT:
01622       if (chan->pvt->send_text)
01623          res = chan->pvt->send_text(chan, (char *) fr->data);
01624       else
01625          res = 0;
01626       break;
01627    case AST_FRAME_HTML:
01628       if (chan->pvt->send_html)
01629          res = chan->pvt->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
01630       else
01631          res = 0;
01632       break;
01633    case AST_FRAME_VIDEO:
01634       /* XXX Handle translation of video codecs one day XXX */
01635       if (chan->pvt->write_video)
01636          res = chan->pvt->write_video(chan, fr);
01637       else
01638          res = 0;
01639       break;
01640    default:
01641       if (chan->pvt->write) {
01642          if (chan->pvt->writetrans) {
01643             f = ast_translate(chan->pvt->writetrans, fr, 0);
01644          } else
01645             f = fr;
01646          if (f) {
01647             res = chan->pvt->write(chan, f);
01648             if( chan->monitor &&
01649                   chan->monitor->write_stream &&
01650                   f && ( f->frametype == AST_FRAME_VOICE ) ) {
01651 #ifndef MONITOR_CONSTANT_DELAY
01652                int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
01653                if (jump >= 0) {
01654                   if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
01655                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01656                   chan->outsmpl += jump + 2 * f->samples;
01657                } else
01658                   chan->outsmpl += f->samples;
01659 #else
01660                int jump = chan->insmpl - chan->outsmpl;
01661                if (jump - MONITOR_DELAY >= 0) {
01662                   if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
01663                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
01664                   chan->outsmpl += jump;
01665                } else
01666                   chan->outsmpl += f->samples;
01667 #endif
01668             if (ast_writestream(chan->monitor->write_stream, f) < 0)
01669                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
01670             }
01671          } else
01672             res = 0;
01673       }
01674    }
01675    if (f && (f != fr))
01676       ast_frfree(f);
01677    chan->blocking = 0;
01678    /* Consider a write failure to force a soft hangup */
01679    if (res < 0)
01680       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01681    else {
01682       if ((chan->fout & 0x7fffffff) == 0x7fffffff)
01683          chan->fout &= 0x80000000;
01684       else
01685          chan->fout++;
01686    }
01687    ast_mutex_unlock(&chan->lock);
01688    return res;
01689 }
01690 
01691 int ast_set_write_format(struct ast_channel *chan, int fmts)
01692 {
01693    int fmt;
01694    int native;
01695    int res;
01696    
01697    ast_mutex_lock(&chan->lock);
01698    native = chan->nativeformats;
01699    fmt = fmts;
01700    
01701    res = ast_translator_best_choice(&native, &fmt);
01702    if (res < 0) {
01703       ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01704          ast_getformatname(fmts), ast_getformatname(chan->nativeformats));
01705       ast_mutex_unlock(&chan->lock);
01706       return -1;
01707    }
01708    
01709    /* Now we have a good choice for both.  We'll write using our native format. */
01710    chan->pvt->rawwriteformat = native;
01711    /* User perspective is fmt */
01712    chan->writeformat = fmt;
01713    /* Free any write translation we have right now */
01714    if (chan->pvt->writetrans)
01715       ast_translator_free_path(chan->pvt->writetrans);
01716    /* Build a translation path from the user write format to the raw writing format */
01717    chan->pvt->writetrans = ast_translator_build_path(chan->pvt->rawwriteformat, chan->writeformat);
01718    if (option_debug)
01719       ast_log(LOG_DEBUG, "Set channel %s to write format %s\n", chan->name, ast_getformatname(chan->writeformat));
01720    ast_mutex_unlock(&chan->lock);
01721    return 0;
01722 }
01723 
01724 int ast_set_read_format(struct ast_channel *chan, int fmts)
01725 {
01726    int fmt;
01727    int native;
01728    int res;
01729    
01730    ast_mutex_lock(&chan->lock);
01731    native = chan->nativeformats;
01732    fmt = fmts;
01733    /* Find a translation path from the native read format to one of the user's read formats */
01734    res = ast_translator_best_choice(&fmt, &native);
01735    if (res < 0) {
01736       ast_log(LOG_NOTICE, "Unable to find a path from %s to %s\n",
01737          ast_getformatname(chan->nativeformats), ast_getformatname(fmts));
01738       ast_mutex_unlock(&chan->lock);
01739       return -1;
01740    }
01741    
01742    /* Now we have a good choice for both.  We'll write using our native format. */
01743    chan->pvt->rawreadformat = native;
01744    /* User perspective is fmt */
01745    chan->readformat = fmt;
01746    /* Free any read translation we have right now */
01747    if (chan->pvt->readtrans)
01748       ast_translator_free_path(chan->pvt->readtrans);
01749    /* Build a translation path from the raw read format to the user reading format */
01750    chan->pvt->readtrans = ast_translator_build_path(chan->readformat, chan->pvt->rawreadformat);
01751    if (option_debug)
01752       ast_log(LOG_DEBUG, "Set channel %s to read format %s\n", 
01753          chan->name, ast_getformatname(chan->readformat));
01754    ast_mutex_unlock(&chan->lock);
01755    return 0;
01756 }
01757 
01758 struct ast_channel *__ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid, struct outgoing_helper *oh)
01759 {
01760    int state = 0;
01761    struct ast_channel *chan;
01762    struct ast_frame *f;
01763    int res = 0;
01764    char *variable;
01765    chan = ast_request(type, format, data);
01766    if (chan) {
01767       if (oh) {
01768          char *tmp, *var;
01769          /* JDG chanvar */
01770          if (oh->variable)
01771             variable = ast_strdupa(oh->variable);
01772          else
01773             variable = NULL;
01774          tmp = variable;
01775          /* FIXME replace this call with strsep  NOT*/
01776          while( (var = strtok_r(NULL, "|", &tmp)) ) {
01777             pbx_builtin_setvar( chan, var );
01778          } /* /JDG */
01779          if (oh->callerid && *oh->callerid)
01780             ast_set_callerid(chan, oh->callerid, 1);
01781          if (oh->account && *oh->account)
01782             ast_cdr_setaccount(chan, oh->account);
01783       }
01784       if (callerid && !ast_strlen_zero(callerid))
01785          ast_set_callerid(chan, callerid, 1);
01786 
01787       if (!ast_call(chan, data, 0)) {
01788          while(timeout && (chan->_state != AST_STATE_UP)) {
01789             res = ast_waitfor(chan, timeout);
01790             if (res < 0) {
01791                /* Something not cool, or timed out */
01792                break;
01793             }
01794             /* If done, break out */
01795             if (!res)
01796                break;
01797             if (timeout > -1)
01798                timeout = res;
01799             f = ast_read(chan);
01800             if (!f) {
01801                state = AST_CONTROL_HANGUP;
01802                res = 0;
01803                break;
01804             }
01805             if (f->frametype == AST_FRAME_CONTROL) {
01806                if (f->subclass == AST_CONTROL_RINGING)
01807                   state = AST_CONTROL_RINGING;
01808                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
01809                   state = f->subclass;
01810                   ast_frfree(f);
01811                   break;
01812                } else if (f->subclass == AST_CONTROL_ANSWER) {
01813                   state = f->subclass;
01814                   ast_frfree(f);
01815                   break;
01816                } else if (f->subclass == AST_CONTROL_PROGRESS) {
01817                   /* Ignore */
01818                } else if (f->subclass == -1) {
01819                   /* Ignore -- just stopping indications */
01820                } else {
01821                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
01822                }
01823             }
01824             ast_frfree(f);
01825          }
01826       } else
01827          ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01828    } else
01829       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
01830    if (chan) {
01831       /* Final fixups */
01832       if (oh) {
01833          if (oh->context && *oh->context)
01834             strncpy(chan->context, oh->context, sizeof(chan->context) - 1);
01835          if (oh->exten && *oh->exten)
01836             strncpy(chan->exten, oh->exten, sizeof(chan->exten) - 1);
01837          chan->priority = oh->priority;
01838       }
01839       if (chan->_state == AST_STATE_UP) 
01840          state = AST_CONTROL_ANSWER;
01841    }
01842    if (outstate)
01843       *outstate = state;
01844    if (chan && res <= 0) {
01845       if (!chan->cdr) {
01846          chan->cdr = ast_cdr_alloc();
01847          if (chan->cdr)
01848             ast_cdr_init(chan->cdr, chan);
01849       }
01850       if (chan->cdr) {
01851          char tmp[256];
01852          snprintf(tmp, 256, "%s/%s", type, (char *)data);
01853          ast_cdr_setapp(chan->cdr,"Dial",tmp);
01854          ast_cdr_update(chan);
01855          ast_cdr_start(chan->cdr);
01856          ast_cdr_end(chan->cdr);
01857          /* If the cause wasn't handled properly */
01858          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
01859             ast_cdr_failed(chan->cdr);
01860       } else 
01861          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
01862       ast_hangup(chan);
01863       chan = NULL;
01864    }
01865    return chan;
01866 }
01867 
01868 struct ast_channel *ast_request_and_dial(char *type, int format, void *data, int timeout, int *outstate, char *callerid)
01869 {
01870    return __ast_request_and_dial(type, format, data, timeout, outstate, callerid, NULL);
01871 }
01872 
01873 struct ast_channel *ast_request(char *type, int format, void *data)
01874 {
01875    struct chanlist *chan;
01876    struct ast_channel *c = NULL;
01877    int capabilities;
01878    int fmt;
01879    int res;
01880    if (ast_mutex_lock(&chlock)) {
01881       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01882       return NULL;
01883    }
01884    chan = backends;
01885    while(chan) {
01886       if (!strcasecmp(type, chan->type)) {
01887          capabilities = chan->capabilities;
01888          fmt = format;
01889          res = ast_translator_best_choice(&fmt, &capabilities);
01890          if (res < 0) {
01891             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->capabilities, format);
01892             ast_mutex_unlock(&chlock);
01893             return NULL;
01894          }
01895          ast_mutex_unlock(&chlock);
01896          if (chan->requester)
01897             c = chan->requester(type, capabilities, data);
01898          if (c) {
01899             if (c->_state == AST_STATE_DOWN) {
01900                manager_event(EVENT_FLAG_CALL, "Newchannel",
01901                "Channel: %s\r\n"
01902                "State: %s\r\n"
01903                "CallerID: %s\r\n"
01904                "Uniqueid: %s\r\n",
01905                c->name, ast_state2str(c->_state), c->callerid ? c->callerid : "<unknown>", c->uniqueid);
01906             }
01907          }
01908          return c;
01909       }
01910       chan = chan->next;
01911    }
01912    if (!chan)
01913       ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
01914    ast_mutex_unlock(&chlock);
01915    return c;
01916 }
01917 
01918 int ast_parse_device_state(char *device)
01919 {
01920    char name[AST_CHANNEL_NAME] = "";
01921    char *cut;
01922    struct ast_channel *chan;
01923 
01924    chan = ast_channel_walk_locked(NULL);
01925    while (chan) {
01926       strncpy(name, chan->name, sizeof(name)-1);
01927       ast_mutex_unlock(&chan->lock);
01928       cut = strchr(name,'-');
01929       if (cut)
01930               *cut = 0;
01931       if (!strcmp(name, device))
01932               return AST_DEVICE_INUSE;
01933       chan = ast_channel_walk_locked(chan);
01934    }
01935    return AST_DEVICE_UNKNOWN;
01936 }
01937 
01938 int ast_device_state(char *device)
01939 {
01940    char tech[AST_MAX_EXTENSION] = "";
01941    char *number;
01942    struct chanlist *chanls;
01943    int res = 0;
01944    
01945    strncpy(tech, device, sizeof(tech)-1);
01946    number = strchr(tech, '/');
01947    if (!number) {
01948        return AST_DEVICE_INVALID;
01949    }
01950    *number = 0;
01951    number++;
01952       
01953    if (ast_mutex_lock(&chlock)) {
01954       ast_log(LOG_WARNING, "Unable to lock channel list\n");
01955       return -1;
01956    }
01957    chanls = backends;
01958    while(chanls) {
01959       if (!strcasecmp(tech, chanls->type)) {
01960          ast_mutex_unlock(&chlock);
01961          if (!chanls->devicestate) 
01962             return ast_parse_device_state(device);
01963          else {
01964             res = chanls->devicestate(number);
01965             if (res == AST_DEVICE_UNKNOWN)
01966                return ast_parse_device_state(device);
01967             else
01968                return res;
01969          }
01970       }
01971       chanls = chanls->next;
01972    }
01973    ast_mutex_unlock(&chlock);
01974    return AST_DEVICE_INVALID;
01975 }
01976 
01977 int ast_call(struct ast_channel *chan, char *addr, int timeout) 
01978 {
01979    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01980       If the remote end does not answer within the timeout, then do NOT hang up, but 
01981       return anyway.  */
01982    int res = -1;
01983    /* Stop if we're a zombie or need a soft hangup */
01984    ast_mutex_lock(&chan->lock);
01985    if (!chan->zombie && !ast_check_hangup(chan)) 
01986       if (chan->pvt->call)
01987          res = chan->pvt->call(chan, addr, timeout);
01988    ast_mutex_unlock(&chan->lock);
01989    return res;
01990 }
01991 
01992 int ast_transfer(struct ast_channel *chan, char *dest) 
01993 {
01994    /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 
01995       If the remote end does not answer within the timeout, then do NOT hang up, but 
01996       return anyway.  */
01997    int res = -1;
01998    /* Stop if we're a zombie or need a soft hangup */
01999    ast_mutex_lock(&chan->lock);
02000    if (!chan->zombie && !ast_check_hangup(chan)) {
02001       if (chan->pvt->transfer) {
02002          res = chan->pvt->transfer(chan, dest);
02003          if (!res)
02004             res = 1;
02005       } else
02006          res = 0;
02007    }
02008    ast_mutex_unlock(&chan->lock);
02009    return res;
02010 }
02011 
02012 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
02013 {
02014    int pos=0;
02015    int to = ftimeout;
02016    int d;
02017    /* XXX Merge with full version? XXX */
02018    /* Stop if we're a zombie or need a soft hangup */
02019    if (c->zombie || ast_check_hangup(c)) 
02020       return -1;
02021    if (!len)
02022       return -1;
02023    do {
02024       if (c->stream) {
02025          d = ast_waitstream(c, AST_DIGIT_ANY);
02026          ast_stopstream(c);
02027          usleep(1000);
02028          if (!d)
02029             d = ast_waitfordigit(c, to);
02030       } else {
02031          d = ast_waitfordigit(c, to);
02032       }
02033       if (d < 0)
02034          return -1;
02035       if (d == 0) {
02036          s[pos]='\0';
02037          return 1;
02038       }
02039       if (!strchr(enders, d))
02040          s[pos++] = d;
02041       if (strchr(enders, d) || (pos >= len)) {
02042          s[pos]='\0';
02043          return 0;
02044       }
02045       to = timeout;
02046    } while(1);
02047    /* Never reached */
02048    return 0;
02049 }
02050 
02051 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
02052 {
02053    int pos=0;
02054    int to = ftimeout;
02055    int d;
02056    /* Stop if we're a zombie or need a soft hangup */
02057    if (c->zombie || ast_check_hangup(c)) 
02058       return -1;
02059    if (!len)
02060       return -1;
02061    do {
02062       if (c->stream) {
02063          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
02064          ast_stopstream(c);
02065          usleep(1000);
02066          if (!d)
02067             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02068       } else {
02069          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
02070       }
02071       if (d < 0)
02072          return -1;
02073       if (d == 0) {
02074          s[pos]='\0';
02075          return 1;
02076       }
02077       if (d == 1) {
02078          s[pos]='\0';
02079          return 2;
02080       }
02081       if (!strchr(enders, d))
02082          s[pos++] = d;
02083       if (strchr(enders, d) || (pos >= len)) {
02084          s[pos]='\0';
02085          return 0;
02086       }
02087       to = timeout;
02088    } while(1);
02089    /* Never reached */
02090    return 0;
02091 }
02092 
02093 int ast_channel_supports_html(struct ast_channel *chan)
02094 {
02095    if (chan->pvt->send_html)
02096       return 1;
02097    return 0;
02098 }
02099 
02100 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, char *data, int datalen)
02101 {
02102    if (chan->pvt->send_html)
02103       return chan->pvt->send_html(chan, subclass, data, datalen);
02104    return -1;
02105 }
02106 
02107 int ast_channel_sendurl(struct ast_channel *chan, char *url)
02108 {
02109    if (chan->pvt->send_html)
02110       return chan->pvt->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
02111    return -1;
02112 }
02113 
02114 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
02115 {
02116    int peerf;
02117    int chanf;
02118    int res;
02119    ast_mutex_lock(&peer->lock);
02120    peerf = peer->nativeformats;
02121    ast_mutex_unlock(&peer->lock);
02122    ast_mutex_lock(&chan->lock);
02123    chanf = chan->nativeformats;
02124    ast_mutex_unlock(&chan->lock);
02125    res = ast_translator_best_choice(&peerf, &chanf);
02126    if (res < 0) {
02127       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, chan->nativeformats, peer->name, peer->nativeformats);
02128       return -1;
02129    }
02130    /* Set read format on channel */
02131    res = ast_set_read_format(chan, peerf);
02132    if (res < 0) {
02133       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, chanf);
02134       return -1;
02135    }
02136    /* Set write format on peer channel */
02137    res = ast_set_write_format(peer, peerf);
02138    if (res < 0) {
02139       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, peerf);
02140       return -1;
02141    }
02142    /* Now we go the other way */
02143    peerf = peer->nativeformats;
02144    chanf = chan->nativeformats;
02145    res = ast_translator_best_choice(&chanf, &peerf);
02146    if (res < 0) {
02147       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, peer->nativeformats, chan->name, chan->nativeformats);
02148       return -1;
02149    }
02150    /* Set writeformat on channel */
02151    res = ast_set_write_format(chan, chanf);
02152    if (res < 0) {
02153       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, chanf);
02154       return -1;
02155    }
02156    /* Set read format on peer channel */
02157    res = ast_set_read_format(peer, chanf);
02158    if (res < 0) {
02159       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, peerf);
02160       return -1;
02161    }
02162    return 0;
02163 }
02164 
02165 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
02166 {
02167    struct ast_frame null = { AST_FRAME_NULL, };
02168    int res = -1;
02169    ast_mutex_lock(&original->lock);
02170    while(ast_mutex_trylock(&clone->lock)) {
02171       ast_mutex_unlock(&original->lock);
02172       usleep(1);
02173       ast_mutex_lock(&original->lock);
02174    }
02175    ast_log(LOG_DEBUG, "Planning to masquerade %s into the structure of %s\n",
02176       clone->name, original->name);
02177    if (original->masq) {
02178       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02179          original->masq->name, original->name);
02180    } else if (clone->masqr) {
02181       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 
02182          clone->name, clone->masqr->name);
02183    } else {
02184       original->masq = clone;
02185       clone->masqr = original;
02186       ast_queue_frame(original, &null);
02187       ast_queue_frame(clone, &null);
02188       ast_log(LOG_DEBUG, "Done planning to masquerade %s into the structure of %s\n", original->name, clone->name);
02189       res = 0;
02190    }
02191    ast_mutex_unlock(&clone->lock);
02192    ast_mutex_unlock(&original->lock);
02193    return res;
02194 }
02195 
02196 void ast_change_name(struct ast_channel *chan, char *newname)
02197 {
02198    char tmp[256];
02199    strncpy(tmp, chan->name, sizeof(tmp) - 1);
02200    strncpy(chan->name, newname, sizeof(chan->name) - 1);
02201    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
02202 }
02203 
02204 int ast_do_masquerade(struct ast_channel *original)
02205 {
02206    int x,i;
02207    int res=0;
02208    int origstate;
02209    char *tmp;
02210    struct ast_var_t *varptr;
02211    struct ast_frame *cur, *prev;
02212    struct ast_channel_pvt *p;
02213    struct ast_channel *clone = original->masq;
02214    int rformat = original->readformat;
02215    int wformat = original->writeformat;
02216    char newn[100];
02217    char orig[100];
02218    char masqn[100];
02219    char zombn[100];
02220 
02221 #if 1
02222    ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
02223       clone->name, clone->_state, original->name, original->_state);
02224 #endif
02225    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
02226       the clone channel into the original channel.  Start by killing off the original
02227       channel's backend.   I'm not sure we're going to keep this function, because 
02228       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
02229 
02230    /* We need the clone's lock, too */
02231    ast_mutex_lock(&clone->lock);
02232 
02233    ast_log(LOG_DEBUG, "Got clone lock on '%s' at %p\n", clone->name, &clone->lock);
02234 
02235    /* Having remembered the original read/write formats, we turn off any translation on either
02236       one */
02237    free_translation(clone);
02238    free_translation(original);
02239 
02240 
02241    /* Unlink the masquerade */
02242    original->masq = NULL;
02243    clone->masqr = NULL;
02244    
02245    /* Save the original name */
02246    strncpy(orig, original->name, sizeof(orig) - 1);
02247    /* Save the new name */
02248    strncpy(newn, clone->name, sizeof(newn) - 1);
02249    /* Create the masq name */
02250    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
02251       
02252    /* Copy the name from the clone channel */
02253    strncpy(original->name, newn, sizeof(original->name)-1);
02254 
02255    /* Mangle the name of the clone channel */
02256    strncpy(clone->name, masqn, sizeof(clone->name) - 1);
02257    
02258    /* Notify any managers of the change, first the masq then the other */
02259    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
02260    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
02261 
02262    /* Swap the guts */  
02263    p = original->pvt;
02264    original->pvt = clone->pvt;
02265    clone->pvt = p;
02266 
02267    /* Save any pending frames on both sides.  Start by counting
02268     * how many we're going to need... */
02269    prev = NULL;
02270    cur = clone->pvt->readq;
02271    x = 0;
02272    while(cur) {
02273       x++;
02274       prev = cur;
02275       cur = cur->next;
02276    }
02277    /* If we had any, prepend them to the ones already in the queue, and 
02278     * load up the alertpipe */
02279    if (prev) {
02280       prev->next = original->pvt->readq;
02281       original->pvt->readq = clone->pvt->readq;
02282       clone->pvt->readq = NULL;
02283       if (original->pvt->alertpipe[1] > -1) {
02284          for (i=0;i<x;i++)
02285             write(original->pvt->alertpipe[1], &x, sizeof(x));
02286       }
02287    }
02288    clone->_softhangup = AST_SOFTHANGUP_DEV;
02289 
02290 
02291    /* And of course, so does our current state.  Note we need not
02292       call ast_setstate since the event manager doesn't really consider
02293       these separate.  We do this early so that the clone has the proper
02294       state of the original channel. */
02295    origstate = original->_state;
02296    original->_state = clone->_state;
02297    clone->_state = origstate;
02298 
02299    if (clone->pvt->fixup){
02300       res = clone->pvt->fixup(original, clone);
02301       if (res) 
02302          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
02303    }
02304 
02305    /* Start by disconnecting the original's physical side */
02306    if (clone->pvt->hangup)
02307       res = clone->pvt->hangup(clone);
02308    if (res) {
02309       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
02310       ast_mutex_unlock(&clone->lock);
02311       return -1;
02312    }
02313    
02314    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
02315    /* Mangle the name of the clone channel */
02316    strncpy(clone->name, zombn, sizeof(clone->name) - 1);
02317    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
02318 
02319    /* Update the type. */
02320    original->type = clone->type;
02321    
02322    /* Keep the same language.  */
02323    strncpy(original->language, clone->language, sizeof(original->language));
02324 
02325    /* Copy the FD's */
02326    for (x=0;x<AST_MAX_FDS;x++) {
02327       original->fds[x] = clone->fds[x];
02328    }
02329    /* Append variables from clone channel into original channel */
02330    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
02331    varptr = original->varshead.first;
02332    if (varptr) {
02333       while(varptr->entries.next) {
02334          varptr = varptr->entries.next;
02335       }
02336       varptr->entries.next = clone->varshead.first;
02337    } else {
02338       original->varshead.first = clone->varshead.first;
02339    }
02340    clone->varshead.first = NULL;
02341    /* Presense of ADSI capable CPE follows clone */
02342    original->adsicpe = clone->adsicpe;
02343    /* Bridge remains the same */
02344    /* CDR fields remain the same */
02345    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
02346    /* Application and data remain the same */
02347    /* Clone exception  becomes real one, as with fdno */
02348    original->exception = clone->exception;
02349    original->fdno = clone->fdno;
02350    /* Schedule context remains the same */
02351    /* Stream stuff stays the same */
02352    /* Keep the original state.  The fixup code will need to work with it most likely */
02353 
02354    /* dnid and callerid change to become the new, HOWEVER, we also link the original's
02355       fields back into the defunct 'clone' so that they will be freed when
02356       ast_frfree is eventually called */
02357    tmp = original->dnid;
02358    original->dnid = clone->dnid;
02359    clone->dnid = tmp;
02360    
02361    tmp = original->callerid;
02362    original->callerid = clone->callerid;
02363    clone->callerid = tmp;
02364    
02365    /* Restore original timing file descriptor */
02366    original->fds[AST_MAX_FDS - 2] = original->timingfd;
02367    
02368    /* Our native formats are different now */
02369    original->nativeformats = clone->nativeformats;
02370    
02371    /* Context, extension, priority, app data, jump table,  remain the same */
02372    /* pvt switches.  pbx stays the same, as does next */
02373    
02374    /* Set the write format */
02375    ast_set_write_format(original, wformat);
02376 
02377    /* Set the read format */
02378    ast_set_read_format(original, rformat);
02379 
02380    /* Copy the music class */
02381    strncpy(original->musicclass, clone->musicclass, sizeof(original->musicclass) - 1);
02382 
02383    ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
02384 
02385    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
02386       can fix up everything as best as possible */
02387    if (original->pvt->fixup) {
02388       res = original->pvt->fixup(clone, original);
02389       if (res) {
02390          ast_log(LOG_WARNING, "Driver for '%s' could not fixup channel %s\n",
02391             original->type, original->name);
02392          ast_mutex_unlock(&clone->lock);
02393          return -1;
02394       }
02395    } else
02396       ast_log(LOG_WARNING, "Driver '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
02397          original->type, original->name);
02398    
02399    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
02400       a zombie so nothing tries to touch it.  If it's already been marked as a
02401       zombie, then free it now (since it already is considered invalid). */
02402    if (clone->zombie) {
02403       ast_log(LOG_DEBUG, "Destroying clone '%s'\n", clone->name);
02404       ast_mutex_unlock(&clone->lock);
02405       ast_channel_free(clone);
02406       manager_event(EVENT_FLAG_CALL, "Hangup", "Channel: %s\r\n", zombn);
02407    } else {
02408       struct ast_frame null_frame = { AST_FRAME_NULL, };
02409       ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
02410       clone->zombie=1;
02411       ast_queue_frame(clone, &null_frame);
02412       ast_mutex_unlock(&clone->lock);
02413    }
02414    
02415    /* Signal any blocker */
02416    if (original->blocking)
02417       pthread_kill(original->blocker, SIGURG);
02418    ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n",
02419       original->name, original->_state);
02420    return 0;
02421 }
02422 
02423 void ast_set_callerid(struct ast_channel *chan, char *callerid, int anitoo)
02424 {
02425    if (chan->callerid)
02426       free(chan->callerid);
02427    if (anitoo && chan->ani)
02428       free(chan->ani);
02429    if (callerid) {
02430       chan->callerid = strdup(callerid);
02431       if (anitoo)
02432          chan->ani = strdup(callerid);
02433    } else {
02434       chan->callerid = NULL;
02435       if (anitoo)
02436          chan->ani = NULL;
02437    }
02438    if (chan->cdr)
02439       ast_cdr_setcid(chan->cdr, chan);
02440    manager_event(EVENT_FLAG_CALL, "Newcallerid", 
02441             "Channel: %s\r\n"
02442             "CallerID: %s\r\n"
02443             "Uniqueid: %s\r\n",
02444             chan->name, chan->callerid ? 
02445             chan->callerid : "<Unknown>",
02446             chan->uniqueid);
02447 }
02448 
02449 int ast_setstate(struct ast_channel *chan, int state)
02450 {
02451    if (chan->_state != state) {
02452       int oldstate = chan->_state;
02453       chan->_state = state;
02454       if (oldstate == AST_STATE_DOWN) {
02455          ast_device_state_changed(chan->name);
02456          manager_event(EVENT_FLAG_CALL, "Newchannel",
02457          "Channel: %s\r\n"
02458          "State: %s\r\n"
02459          "CallerID: %s\r\n"
02460          "Uniqueid: %s\r\n",
02461          chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02462       } else {
02463          manager_event(EVENT_FLAG_CALL, "Newstate", 
02464             "Channel: %s\r\n"
02465             "State: %s\r\n"
02466             "CallerID: %s\r\n"
02467             "Uniqueid: %s\r\n",
02468             chan->name, ast_state2str(chan->_state), chan->callerid ? chan->callerid : "<unknown>", chan->uniqueid);
02469       }
02470    }
02471    return 0;
02472 }
02473 
02474 static long tvdiff(struct timeval *now, struct timeval *then) 
02475 {
02476    return (((now->tv_sec * 1000) + now->tv_usec / 1000) - ((then->tv_sec * 1000) + then->tv_usec / 1000));
02477 }
02478 
02479 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, char *sound, int remain) 
02480 {
02481    int res=0, min=0, sec=0,check=0;
02482 
02483    check = ast_autoservice_start(peer);
02484    if(check) 
02485       return;
02486 
02487    if (remain > 0) {
02488       if (remain / 60 > 1) {
02489          min = remain / 60;
02490          sec = remain % 60;
02491       } else {
02492          sec = remain;
02493       }
02494    }
02495    
02496    if (!strcmp(sound,"timeleft")) {
02497       res = ast_streamfile(chan, "vm-youhave", chan->language);
02498       res = ast_waitstream(chan, "");
02499       if (min) {
02500          res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL);
02501          res = ast_streamfile(chan, "queue-minutes", chan->language);
02502          res = ast_waitstream(chan, "");
02503       }
02504       if (sec) {
02505          res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL);
02506          res = ast_streamfile(chan, "queue-seconds", chan->language);
02507          res = ast_waitstream(chan, "");
02508       }
02509    } else {
02510       res = ast_streamfile(chan, sound, chan->language);
02511       res = ast_waitstream(chan, "");
02512    }
02513 
02514    check = ast_autoservice_stop(peer);
02515 }
02516 
02517 int ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc) 
02518 {
02519    /* Copy voice back and forth between the two channels.   Give the peer
02520       the ability to transfer calls with '#<extension' syntax. */
02521    int flags;
02522    struct ast_channel *cs[3];
02523    int to = -1;
02524    struct ast_frame *f;
02525    struct ast_channel *who = NULL;
02526    int res=0;
02527    int nativefailed=0;
02528    int firstpass;
02529    int o0nativeformats;
02530    int o1nativeformats;
02531    struct timeval start_time,precise_now;
02532    long elapsed_ms=0, time_left_ms=0;
02533    int playit=0, playitagain=1, first_time=1;
02534 
02535    flags = (config->allowdisconnect_out||config->allowredirect_out ? AST_BRIDGE_DTMF_CHANNEL_0 : 0) + (config->allowdisconnect_in||config->allowredirect_in ? AST_BRIDGE_DTMF_CHANNEL_1 : 0);
02536 
02537    firstpass = config->firstpass;
02538    config->firstpass = 0;
02539 
02540    /* timestamp */
02541    gettimeofday(&start_time,NULL);
02542    time_left_ms = config->timelimit;
02543 
02544    if (config->play_to_caller && config->start_sound && firstpass)
02545       bridge_playfile(c0,c1,config->start_sound,time_left_ms / 1000);
02546    if (config->play_to_callee && config->start_sound && firstpass)
02547       bridge_playfile(c1,c0,config->start_sound,time_left_ms / 1000);
02548 
02549    /* Stop if we're a zombie or need a soft hangup */
02550    if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) 
02551       return -1;
02552    if (c0->bridge) {
02553       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02554          c0->name, c0->bridge->name);
02555       return -1;
02556    }
02557    if (c1->bridge) {
02558       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 
02559          c1->name, c1->bridge->name);
02560       return -1;
02561    }
02562    
02563    /* Keep track of bridge */
02564    c0->bridge = c1;
02565    c1->bridge = c0;
02566    cs[0] = c0;
02567    cs[1] = c1;
02568    
02569    manager_event(EVENT_FLAG_CALL, "Link", 
02570          "Channel1: %s\r\n"
02571          "Channel2: %s\r\n"
02572          "Uniqueid1: %s\r\n"
02573          "Uniqueid2: %s\r\n",
02574          c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02575    o1nativeformats = c1->nativeformats;
02576    o0nativeformats = c0->nativeformats;
02577    for (/* ever */;;) {
02578       /* timestamp */
02579       if (config->timelimit) {
02580          gettimeofday(&precise_now,NULL);
02581          elapsed_ms = tvdiff(&precise_now,&start_time);
02582          time_left_ms = config->timelimit - elapsed_ms;
02583 
02584          if (playitagain && (config->play_to_caller || config->play_to_callee) && (config->play_warning && time_left_ms <= config->play_warning)) { 
02585             /* narrowing down to the end */
02586             if (config->warning_freq == 0) {
02587                playit = 1;
02588                first_time=0;
02589                playitagain=0;
02590             } else if (first_time) {
02591                playit = 1;
02592                first_time=0;
02593             } else {
02594                if ((time_left_ms % config->warning_freq) <= 50) {
02595                   playit = 1;
02596                }
02597             }
02598          }
02599          if (time_left_ms <= 0) {
02600             if (config->play_to_caller && config->end_sound)
02601                bridge_playfile(c0,c1,config->end_sound,0);
02602             if (config->play_to_callee && config->end_sound)
02603                bridge_playfile(c1,c0,config->end_sound,0);
02604             *fo = NULL;
02605             if (who) *rc = who;
02606             res = 0;
02607             break;
02608          }
02609          if (time_left_ms >= 5000 && playit) {
02610             if (config->play_to_caller && config->warning_sound && config->play_warning)
02611                bridge_playfile(c0,c1,config->warning_sound,time_left_ms / 1000);
02612             if (config->play_to_callee && config->warning_sound && config->play_warning)
02613                bridge_playfile(c1,c0,config->warning_sound,time_left_ms / 1000);
02614             playit = 0;
02615          }
02616          
02617       }
02618       /* Stop if we're a zombie or need a soft hangup */
02619       if (c0->zombie || ast_check_hangup_locked(c0) || c1->zombie || ast_check_hangup_locked(c1)) {
02620          *fo = NULL;
02621          if (who) *rc = who;
02622          res = 0;
02623          ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",c0->name,c1->name,c0->zombie?"Yes":"No",ast_check_hangup(c0)?"Yes":"No",c1->zombie?"Yes":"No",ast_check_hangup(c1)?"Yes":"No");
02624          break;
02625       }
02626       if (c0->pvt->bridge && config->timelimit==0 &&
02627          (c0->pvt->bridge == c1->pvt->bridge) && !nativefailed && !c0->monitor && !c1->monitor) {
02628             /* Looks like they share a bridge code */
02629          if (option_verbose > 2) 
02630             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
02631          if (!(res = c0->pvt->bridge(c0, c1, flags, fo, rc))) {
02632             c0->bridge = NULL;
02633             c1->bridge = NULL;
02634             manager_event(EVENT_FLAG_CALL, "Unlink", 
02635                "Channel1: %s\r\n"
02636                "Channel2: %s\r\n"
02637                "Uniqueid1: %s\r\n"
02638                "Uniqueid2: %s\r\n",
02639                c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02640             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n",c0->name ,c1->name);
02641             return 0;
02642          }
02643          /* If they return non-zero then continue on normally.  Let "-2" mean don't worry about
02644             my not wanting to bridge */
02645          if ((res != -2) && (res != -3))
02646             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
02647          if (res != -3) nativefailed++;
02648       }
02649    
02650       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
02651          !(c0->generator || c1->generator))  {
02652          if (ast_channel_make_compatible(c0, c1)) {
02653             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
02654             manager_event(EVENT_FLAG_CALL, "Unlink", 
02655                "Channel1: %s\r\n"
02656                "Channel2: %s\r\n"
02657                "Uniqueid1: %s\r\n"
02658                "Uniqueid2: %s\r\n",
02659                c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02660             return -1;
02661          }
02662          o0nativeformats = c0->nativeformats;
02663          o1nativeformats = c1->nativeformats;
02664       }
02665       who = ast_waitfor_n(cs, 2, &to);
02666       if (!who) {
02667          ast_log(LOG_DEBUG, "Nobody there, continuing...\n"); 
02668          continue;
02669       }
02670       f = ast_read(who);
02671       if (!f) {
02672          *fo = NULL;
02673          *rc = who;
02674          res = 0;
02675          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
02676          break;
02677       }
02678 
02679       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
02680          *fo = f;
02681          *rc = who;
02682          res =  0;
02683          ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
02684          break;
02685       }
02686       if ((f->frametype == AST_FRAME_VOICE) ||
02687          (f->frametype == AST_FRAME_TEXT) ||
02688          (f->frametype == AST_FRAME_VIDEO) || 
02689          (f->frametype == AST_FRAME_IMAGE) ||
02690          (f->frametype == AST_FRAME_HTML) ||
02691          (f->frametype == AST_FRAME_DTMF)) {
02692          if ((f->frametype == AST_FRAME_DTMF) && 
02693             (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
02694             if ((who == c0)) {
02695                if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
02696                   *rc = c0;
02697                   *fo = f;
02698                   /* Take out of conference mode */
02699                   res = 0;
02700                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_0 on c0 (%s)\n",c0->name);
02701                   break;
02702                } else 
02703                   goto tackygoto;
02704             } else
02705             if ((who == c1)) {
02706                if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
02707                   *rc = c1;
02708                   *fo = f;
02709                   res =  0;
02710                   ast_log(LOG_DEBUG, "Got AST_BRIDGE_DTMF_CHANNEL_1 on c1 (%s)\n",c1->name);
02711                   break;
02712                } else
02713                   goto tackygoto;
02714             }
02715          } else {
02716 #if 0
02717             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
02718             if (who == last) 
02719                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
02720             last = who;
02721 #endif
02722 tackygoto:
02723             /* Don't copy packets if there is a generator on either one, since they're
02724                not supposed to be listening anyway */
02725             if (who == c0) 
02726                ast_write(c1, f);
02727             else 
02728                ast_write(c0, f);
02729          }
02730          ast_frfree(f);
02731       } else
02732          ast_frfree(f);
02733       /* Swap who gets priority */
02734       cs[2] = cs[0];
02735       cs[0] = cs[1];
02736       cs[1] = cs[2];
02737    }
02738    c0->bridge = NULL;
02739    c1->bridge = NULL;
02740    manager_event(EVENT_FLAG_CALL, "Unlink", 
02741                "Channel1: %s\r\n"
02742                "Channel2: %s\r\n"
02743                "Uniqueid1: %s\r\n"
02744                "Uniqueid2: %s\r\n",
02745                c0->name, c1->name, c0->uniqueid, c1->uniqueid);
02746    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n",c0->name,c1->name);
02747    return res;
02748 }
02749 
02750 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
02751 {
02752    int res;
02753    if (chan->pvt->setoption) {
02754       res = chan->pvt->setoption(chan, option, data, datalen);
02755       if (res < 0)
02756          return res;
02757    } else {
02758       errno = ENOSYS;
02759       return -1;
02760    }
02761    if (block) {
02762       /* XXX Implement blocking -- just wait for our option frame reply, discarding
02763          intermediate packets. XXX */
02764       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
02765       return -1;
02766    }
02767    return 0;
02768 }
02769 
02770 struct tonepair_def {
02771    int freq1;
02772    int freq2;
02773    int duration;
02774    int vol;
02775 };
02776 
02777 struct tonepair_state {
02778    float freq1;
02779    float freq2;
02780    float vol;
02781    int duration;
02782    int pos;
02783    int origwfmt;
02784    struct ast_frame f;
02785    unsigned char offset[AST_FRIENDLY_OFFSET];
02786    short data[4000];
02787 };
02788 
02789 static void tonepair_release(struct ast_channel *chan, void *params)
02790 {
02791    struct tonepair_state *ts = params;
02792    if (chan) {
02793       ast_set_write_format(chan, ts->origwfmt);
02794    }
02795    free(ts);
02796 }
02797 
02798 static void * tonepair_alloc(struct ast_channel *chan, void *params)
02799 {
02800    struct tonepair_state *ts;
02801    struct tonepair_def *td = params;
02802    ts = malloc(sizeof(struct tonepair_state));
02803    if (!ts)
02804       return NULL;
02805    memset(ts, 0, sizeof(struct tonepair_state));
02806    ts->origwfmt = chan->writeformat;
02807    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
02808       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
02809       tonepair_release(NULL, ts);
02810       ts = NULL;
02811    } else {
02812       ts->freq1 = td->freq1;
02813       ts->freq2 = td->freq2;
02814       ts->duration = td->duration;
02815       ts->vol = td->vol;
02816    }
02817    /* Let interrupts interrupt :) */
02818    chan->writeinterrupt = 1;
02819    return ts;
02820 }
02821 
02822 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
02823 {
02824    struct tonepair_state *ts = data;
02825    int x;
02826 
02827    /* we need to prepare a frame with 16 * timelen samples as we're 
02828     * generating SLIN audio
02829     */
02830    len = samples * 2;
02831 
02832    if (len > sizeof(ts->data) / 2 - 1) {
02833       ast_log(LOG_WARNING, "Can't generate that much data!\n");
02834       return -1;
02835    }
02836    memset(&ts->f, 0, sizeof(ts->f));
02837    for (x=0;x<len/2;x++) {
02838       ts->data[x] = ts->vol * (
02839             sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
02840             sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
02841          );
02842    }
02843    ts->f.frametype = AST_FRAME_VOICE;
02844    ts->f.subclass = AST_FORMAT_SLINEAR;
02845    ts->f.datalen = len;
02846    ts->f.samples = samples;
02847    ts->f.offset = AST_FRIENDLY_OFFSET;
02848    ts->f.data = ts->data;
02849    ast_write(chan, &ts->f);
02850    ts->pos += x;
02851    if (ts->duration > 0) {
02852       if (ts->pos >= ts->duration * 8)
02853          return -1;
02854    }
02855    return 0;
02856 }
02857 
02858 static struct ast_generator tonepair = {
02859    alloc: tonepair_alloc,
02860    release: tonepair_release,
02861    generate: tonepair_generator,
02862 };
02863 
02864 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
02865 {
02866    struct tonepair_def d = { 0, };
02867    d.freq1 = freq1;
02868    d.freq2 = freq2;
02869    d.duration = duration;
02870    if (vol < 1)
02871       d.vol = 8192;
02872    else
02873       d.vol = vol;
02874    if (ast_activate_generator(chan, &tonepair, &d))
02875       return -1;
02876    return 0;
02877 }
02878 
02879 void ast_tonepair_stop(struct ast_channel *chan)
02880 {
02881    ast_deactivate_generator(chan);
02882 }
02883 
02884 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
02885 {
02886    struct ast_frame *f;
02887    int res;
02888    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
02889       return res;
02890 
02891    /* Give us some wiggle room */
02892    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
02893       f = ast_read(chan);
02894       if (f)
02895          ast_frfree(f);
02896       else
02897          return -1;
02898    }
02899    return 0;
02900 }
02901 
02902 unsigned int ast_get_group(char *s)
02903 {
02904    char *copy;
02905    char *piece;
02906    char *c=NULL;
02907    int start=0, finish=0,x;
02908    unsigned int group = 0;
02909    copy = ast_strdupa(s);
02910    if (!copy) {
02911       ast_log(LOG_ERROR, "Out of memory\n");
02912       return 0;
02913    }
02914    c = copy;
02915    
02916    while((piece = strsep(&c, ","))) {
02917       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
02918          /* Range */
02919       } else if (sscanf(piece, "%d", &start)) {
02920          /* Just one */
02921          finish = start;
02922       } else {
02923          ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.\n", s, piece);
02924          continue;
02925       }
02926       for (x=start;x<=finish;x++) {
02927          if ((x > 31) || (x < 0)) {
02928             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 31)\n", x);
02929          } else
02930             group |= (1 << x);
02931       }
02932    }
02933    return group;
02934 }

Generated on Wed Aug 10 11:36:31 2005 for Asterisk by  doxygen 1.4.4