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

Generated on Fri Oct 31 07:05:05 2003 for Asterisk by doxygen 1.3.4