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

Generated on Fri Feb 27 12:19:41 2004 for Asterisk by doxygen 1.3.5