Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:53 2009

## Asterisk developer's documentation

- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Directories

# channel.c

Go to the documentation of this file.

    00001 /*
    00002  * Asterisk -- An open source telephony toolkit.
    00003  *
    00004  * Copyright (C) 1999 - 2006, Digium, Inc.
    00005  *
    00006  * Mark Spencer <markster@digium.com>
    00007  *
    00008  * See http://www.asterisk.org for more information about
    00009  * the Asterisk project. Please do not directly contact
    00010  * any of the maintainers of this project for assistance;
    00011  * the project provides a web site, mailing lists and IRC
    00012  * channels for your use.
    00013  *
    00014  * This program is free software, distributed under the terms of
    00015  * the GNU General Public License Version 2. See the LICENSE file
    00016  * at the top of the source tree.
    00017  */
    00018
    00019 /*! \file
    00020  *
    00021  * \brief Channel Management
    00022  *
    00023  */
    00024
    00025 #include <stdio.h>
    00026 #include <stdlib.h>
    00027 #include <string.h>
    00028 #include <sys/time.h>
    00029 #include <signal.h>
    00030 #include <errno.h>
    00031 #include <unistd.h>
    00032 #include <math.h>       /* For PI */
    00033
    00034 #ifdef ZAPTEL_OPTIMIZATIONS
    00035 #include <sys/ioctl.h>
    00036 #ifdef __linux__
    00037 #include <linux/zaptel.h>
    00038 #else
    00039 #include <zaptel.h>
    00040 #endif /* __linux__ */
    00041 #ifndef ZT_TIMERPING
    00042 #error "You need newer zaptel!  Please svn update zaptel"
    00043 #endif
    00044 #endif
    00045
    00046 #include "asterisk.h"
    00047
    00048 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 211526 $")
    00049
    00050 #include "asterisk/pbx.h"
    00051 #include "asterisk/frame.h"
    00052 #include "asterisk/sched.h"
    00053 #include "asterisk/options.h"
    00054 #include "asterisk/channel.h"
    00055 #include "asterisk/chanspy.h"
    00056 #include "asterisk/musiconhold.h"
    00057 #include "asterisk/logger.h"
    00058 #include "asterisk/say.h"
    00059 #include "asterisk/file.h"
    00060 #include "asterisk/cli.h"
    00061 #include "asterisk/translate.h"
    00062 #include "asterisk/manager.h"
    00063 #include "asterisk/chanvars.h"
    00064 #include "asterisk/linkedlists.h"
    00065 #include "asterisk/indications.h"
    00066 #include "asterisk/monitor.h"
    00067 #include "asterisk/causes.h"
    00068 #include "asterisk/callerid.h"
    00069 #include "asterisk/utils.h"
    00070 #include "asterisk/lock.h"
    00071 #include "asterisk/app.h"
    00072 #include "asterisk/transcap.h"
    00073 #include "asterisk/devicestate.h"
    00074
    00075 struct channel_spy_trans {
    00076    int last_format;
    00077    struct ast_trans_pvt *path;
    00078 };
    00079
    00080 struct ast_channel_spy_list {
    00081    struct channel_spy_trans read_translator;
    00082    struct channel_spy_trans write_translator;
    00083    AST_LIST_HEAD_NOLOCK(, ast_channel_spy) list;
    00084 };
    00085
    00086 /* uncomment if you have problems with 'monitoring' synchronized files */
    00087 #if 0
    00088 #define MONITOR_CONSTANT_DELAY
    00089 #define MONITOR_DELAY   150 * 8     /* 150 ms of MONITORING DELAY */
    00090 #endif
    00091
    00092 /*
    00093  * Prevent new channel allocation if shutting down.
    00094  */
    00095 static int shutting_down = 0;
    00096
    00097 AST_MUTEX_DEFINE_STATIC(uniquelock);
    00098 static int uniqueint = 0;
    00099
    00100 unsigned long global_fin = 0, global_fout = 0;
    00101
    00102 /* XXX Lock appropriately in more functions XXX */
    00103
    00104 struct chanlist {
    00105    const struct ast_channel_tech *tech;
    00106    struct chanlist *next;
    00107 };
    00108
    00109 static struct chanlist *backends = NULL;
    00110
    00111 /*
    00112  * the list of channels we have
    00113  */
    00114 static struct ast_channel *channels = NULL;
    00115
    00116 /* Protect the channel list, both backends and channels.
    00117  */
    00118 AST_MUTEX_DEFINE_STATIC(chlock);
    00119
    00120 const struct ast_cause {
    00121    int cause;
    00122    const char *desc;
    00123 } causes[] = {
    00124    { AST_CAUSE_UNALLOCATED, "Unallocated (unassigned) number" },
    00125    { AST_CAUSE_NO_ROUTE_TRANSIT_NET, "No route to specified transmit network" },
    00126    { AST_CAUSE_NO_ROUTE_DESTINATION, "No route to destination" },
    00127    { AST_CAUSE_CHANNEL_UNACCEPTABLE, "Channel unacceptable" },
    00128    { AST_CAUSE_CALL_AWARDED_DELIVERED, "Call awarded and being delivered in an established channel" },
    00129    { AST_CAUSE_NORMAL_CLEARING, "Normal Clearing" },
    00130    { AST_CAUSE_USER_BUSY, "User busy" },
    00131    { AST_CAUSE_NO_USER_RESPONSE, "No user responding" },
    00132    { AST_CAUSE_NO_ANSWER, "User alerting, no answer" },
    00133    { AST_CAUSE_CALL_REJECTED, "Call Rejected" },
    00134    { AST_CAUSE_NUMBER_CHANGED, "Number changed" },
    00135    { AST_CAUSE_DESTINATION_OUT_OF_ORDER, "Destination out of order" },
    00136    { AST_CAUSE_INVALID_NUMBER_FORMAT, "Invalid number format" },
    00137    { AST_CAUSE_FACILITY_REJECTED, "Facility rejected" },
    00138    { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "Response to STATus ENQuiry" },
    00139    { AST_CAUSE_NORMAL_UNSPECIFIED, "Normal, unspecified" },
    00140    { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "Circuit/channel congestion" },
    00141    { AST_CAUSE_NETWORK_OUT_OF_ORDER, "Network out of order" },
    00142    { AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "Temporary failure" },
    00143    { AST_CAUSE_SWITCH_CONGESTION, "Switching equipment congestion" },
    00144    { AST_CAUSE_ACCESS_INFO_DISCARDED, "Access information discarded" },
    00145    { AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "Requested channel not available" },
    00146    { AST_CAUSE_PRE_EMPTED, "Pre-empted" },
    00147    { AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "Facility not subscribed" },
    00148    { AST_CAUSE_OUTGOING_CALL_BARRED, "Outgoing call barred" },
    00149    { AST_CAUSE_INCOMING_CALL_BARRED, "Incoming call barred" },
    00150    { AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "Bearer capability not authorized" },
    00151    { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "Bearer capability not available" },
    00152    { AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "Bearer capability not implemented" },
    00153    { AST_CAUSE_CHAN_NOT_IMPLEMENTED, "Channel not implemented" },
    00154    { AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "Facility not implemented" },
    00155    { AST_CAUSE_INVALID_CALL_REFERENCE, "Invalid call reference value" },
    00156    { AST_CAUSE_INCOMPATIBLE_DESTINATION, "Incompatible destination" },
    00157    { AST_CAUSE_INVALID_MSG_UNSPECIFIED, "Invalid message unspecified" },
    00158    { AST_CAUSE_MANDATORY_IE_MISSING, "Mandatory information element is missing" },
    00159    { AST_CAUSE_MESSAGE_TYPE_NONEXIST, "Message type nonexist." },
    00160    { AST_CAUSE_WRONG_MESSAGE, "Wrong message" },
    00161    { AST_CAUSE_IE_NONEXIST, "Info. element nonexist or not implemented" },
    00162    { AST_CAUSE_INVALID_IE_CONTENTS, "Invalid information element contents" },
    00163    { AST_CAUSE_WRONG_CALL_STATE, "Message not compatible with call state" },
    00164    { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "Recover on timer expiry" },
    00165    { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "Mandatory IE length error" },
    00166    { AST_CAUSE_PROTOCOL_ERROR, "Protocol error, unspecified" },
    00167    { AST_CAUSE_INTERWORKING, "Interworking, unspecified" },
    00168 };
    00169
    00170
    00171 static int show_channeltypes(int fd, int argc, char *argv[])
    00172 {
    00173 #define FORMAT  "%-10.10s  %-30.30s %-12.12s %-12.12s %-12.12s\n"
    00174    struct chanlist *cl = backends;
    00175    ast_cli(fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
    00176    ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
    00177    if (ast_mutex_lock(&chlock)) {
    00178       ast_log(LOG_WARNING, "Unable to lock channel list\n");
    00179       return -1;
    00180    }
    00181    while (cl) {
    00182       ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
    00183          (cl->tech->devicestate) ? "yes" : "no",
    00184          (cl->tech->indicate) ? "yes" : "no",
    00185          (cl->tech->transfer) ? "yes" : "no");
    00186       cl = cl->next;
    00187    }
    00188    ast_mutex_unlock(&chlock);
    00189    return RESULT_SUCCESS;
    00190
    00191 #undef FORMAT
    00192
    00193 }
    00194
    00195 static char show_channeltypes_usage[] =
    00196 "Usage: show channeltypes\n"
    00197 "       Shows available channel types registered in your Asterisk server.\n";
    00198
    00199 static struct ast_cli_entry cli_show_channeltypes =
    00200    { { "show", "channeltypes", NULL }, show_channeltypes, "Show available channel types", show_channeltypes_usage };
    00201
    00202 /*--- ast_check_hangup: Checks to see if a channel is needing hang up */
    00203 int ast_check_hangup(struct ast_channel *chan)
    00204 {
    00205    time_t   myt;
    00206
    00207    /* if soft hangup flag, return true */
    00208    if (chan->_softhangup)
    00209       return 1;
    00210    /* if no technology private data, return true */
    00211    if (!chan->tech_pvt)
    00212       return 1;
    00213    /* if no hangup scheduled, just return here */
    00214    if (!chan->whentohangup)
    00215       return 0;
    00216    time(&myt); /* get current time */
    00217    /* return, if not yet */
    00218    if (chan->whentohangup > myt)
    00219       return 0;
    00220    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
    00221    return 1;
    00222 }
    00223
    00224 static int ast_check_hangup_locked(struct ast_channel *chan)
    00225 {
    00226    int res;
    00227    ast_mutex_lock(&chan->lock);
    00228    res = ast_check_hangup(chan);
    00229    ast_mutex_unlock(&chan->lock);
    00230    return res;
    00231 }
    00232
    00233 /*--- ast_begin_shutdown: Initiate system shutdown */
    00234 void ast_begin_shutdown(int hangup)
    00235 {
    00236    struct ast_channel *c;
    00237    shutting_down = 1;
    00238    if (hangup) {
    00239       ast_mutex_lock(&chlock);
    00240       c = channels;
    00241       while(c) {
    00242          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
    00243          c = c->next;
    00244       }
    00245       ast_mutex_unlock(&chlock);
    00246    }
    00247 }
    00248
    00249 /*--- ast_active_channels: returns number of active/allocated channels */
    00250 int ast_active_channels(void)
    00251 {
    00252    struct ast_channel *c;
    00253    int cnt = 0;
    00254    ast_mutex_lock(&chlock);
    00255    c = channels;
    00256    while(c) {
    00257       cnt++;
    00258       c = c->next;
    00259    }
    00260    ast_mutex_unlock(&chlock);
    00261    return cnt;
    00262 }
    00263
    00264 /*--- ast_cancel_shutdown: Cancel a shutdown in progress */
    00265 void ast_cancel_shutdown(void)
    00266 {
    00267    shutting_down = 0;
    00268 }
    00269
    00270 /*--- ast_shutting_down: Returns non-zero if Asterisk is being shut down */
    00271 int ast_shutting_down(void)
    00272 {
    00273    return shutting_down;
    00274 }
    00275
    00276 /*--- ast_channel_setwhentohangup: Set when to hangup channel */
    00277 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
    00278 {
    00279    time_t   myt;
    00280    struct ast_frame fr = { AST_FRAME_NULL, };
    00281
    00282    time(&myt);
    00283    if (offset)
    00284       chan->whentohangup = myt + offset;
    00285    else
    00286       chan->whentohangup = 0;
    00287    ast_queue_frame(chan, &fr);
    00288    return;
    00289 }
    00290
    00291 /*--- ast_channel_cmpwhentohangup: Compare a offset with when to hangup channel */
    00292 int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
    00293 {
    00294    time_t whentohangup;
    00295
    00296    if (chan->whentohangup == 0) {
    00297       if (offset == 0)
    00298          return (0);
    00299       else
    00300          return (-1);
    00301    } else {
    00302       if (offset == 0)
    00303          return (1);
    00304       else {
    00305          whentohangup = offset + time (NULL);
    00306          if (chan->whentohangup < whentohangup)
    00307             return (1);
    00308          else if (chan->whentohangup == whentohangup)
    00309             return (0);
    00310          else
    00311             return (-1);
    00312       }
    00313    }
    00314 }
    00315
    00316 /*--- ast_channel_register: Register a new telephony channel in Asterisk */
    00317 int ast_channel_register(const struct ast_channel_tech *tech)
    00318 {
    00319    struct chanlist *chan;
    00320
    00321    ast_mutex_lock(&chlock);
    00322
    00323    chan = backends;
    00324    while (chan) {
    00325       if (!strcasecmp(tech->type, chan->tech->type)) {
    00326          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
    00327          ast_mutex_unlock(&chlock);
    00328          return -1;
    00329       }
    00330       chan = chan->next;
    00331    }
    00332
    00333    chan = malloc(sizeof(*chan));
    00334    if (!chan) {
    00335       ast_log(LOG_WARNING, "Out of memory\n");
    00336       ast_mutex_unlock(&chlock);
    00337       return -1;
    00338    }
    00339    chan->tech = tech;
    00340    chan->next = backends;
    00341    backends = chan;
    00342
    00343    if (option_debug)
    00344       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
    00345
    00346    if (option_verbose > 1)
    00347       ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
    00348              chan->tech->description);
    00349
    00350    ast_mutex_unlock(&chlock);
    00351    return 0;
    00352 }
    00353
    00354 void ast_channel_unregister(const struct ast_channel_tech *tech)
    00355 {
    00356    struct chanlist *chan, *last=NULL;
    00357
    00358    if (option_debug && tech && tech->type )
    00359       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
    00360    else if (option_debug)
    00361       ast_log(LOG_DEBUG, "Unregistering channel, tech is NULL!!!\n");
    00362
    00363
    00364    ast_mutex_lock(&chlock);
    00365
    00366    chan = backends;
    00367    while (chan) {
    00368       if (chan->tech == tech) {
    00369          if (last)
    00370             last->next = chan->next;
    00371          else
    00372             backends = backends->next;
    00373          free(chan);
    00374          ast_mutex_unlock(&chlock);
    00375
    00376          if (option_verbose > 1)
    00377             ast_verbose( VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
    00378
    00379          return;
    00380       }
    00381       last = chan;
    00382       chan = chan->next;
    00383    }
    00384
    00385    ast_mutex_unlock(&chlock);
    00386 }
    00387
    00388 const struct ast_channel_tech *ast_get_channel_tech(const char *name)
    00389 {
    00390    struct chanlist *chanls;
    00391
    00392    if (ast_mutex_lock(&chlock)) {
    00393       ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
    00394       return NULL;
    00395    }
    00396
    00397    for (chanls = backends; chanls; chanls = chanls->next) {
    00398       if (strcasecmp(name, chanls->tech->type))
    00399          continue;
    00400
    00401       ast_mutex_unlock(&chlock);
    00402       return chanls->tech;
    00403    }
    00404
    00405    ast_mutex_unlock(&chlock);
    00406    return NULL;
    00407 }
    00408
    00409 /*--- ast_cause2str: Gives the string form of a given hangup cause */
    00410 const char *ast_cause2str(int cause)
    00411 {
    00412    int x;
    00413
    00414    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++)
    00415       if (causes[x].cause == cause)
    00416          return causes[x].desc;
    00417
    00418    return "Unknown";
    00419 }
    00420
    00421 /*--- ast_state2str: Gives the string form of a given channel state */
    00422 char *ast_state2str(int state)
    00423 {
    00424    /* XXX Not reentrant XXX */
    00425    static char localtmp[256];
    00426    switch(state) {
    00427    case AST_STATE_DOWN:
    00428       return "Down";
    00429    case AST_STATE_RESERVED:
    00430       return "Rsrvd";
    00431    case AST_STATE_OFFHOOK:
    00432       return "OffHook";
    00433    case AST_STATE_DIALING:
    00434       return "Dialing";
    00435    case AST_STATE_RING:
    00436       return "Ring";
    00437    case AST_STATE_RINGING:
    00438       return "Ringing";
    00439    case AST_STATE_UP:
    00440       return "Up";
    00441    case AST_STATE_BUSY:
    00442       return "Busy";
    00443    default:
    00444       snprintf(localtmp, sizeof(localtmp), "Unknown (%d)\n", state);
    00445       return localtmp;
    00446    }
    00447 }
    00448
    00449 /*--- ast_transfercapability2str: Gives the string form of a given transfer capability */
    00450 char *ast_transfercapability2str(int transfercapability)
    00451 {
    00452    switch(transfercapability) {
    00453    case AST_TRANS_CAP_SPEECH:
    00454       return "SPEECH";
    00455    case AST_TRANS_CAP_DIGITAL:
    00456       return "DIGITAL";
    00457    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
    00458       return "RESTRICTED_DIGITAL";
    00459    case AST_TRANS_CAP_3_1K_AUDIO:
    00460       return "3K1AUDIO";
    00461    case AST_TRANS_CAP_DIGITAL_W_TONES:
    00462       return "DIGITAL_W_TONES";
    00463    case AST_TRANS_CAP_VIDEO:
    00464       return "VIDEO";
    00465    default:
    00466       return "UNKNOWN";
    00467    }
    00468 }
    00469
    00470 /*--- ast_best_codec: Pick the best codec */
    00471 int ast_best_codec(int fmts)
    00472 {
    00473    /* This just our opinion, expressed in code.  We are asked to choose
    00474       the best codec to use, given no information */
    00475    int x;
    00476    static int prefs[] =
    00477    {
    00478       /* Okay, ulaw is used by all telephony equipment, so start with it */
    00479       AST_FORMAT_ULAW,
    00480       /* Unless of course, you're a silly European, so then prefer ALAW */
    00481       AST_FORMAT_ALAW,
    00482       /* Okay, well, signed linear is easy to translate into other stuff */
    00483       AST_FORMAT_SLINEAR,
    00484       /* G.726 is standard ADPCM */
    00485       AST_FORMAT_G726,
    00486       /* ADPCM has great sound quality and is still pretty easy to translate */
    00487       AST_FORMAT_ADPCM,
    00488       /* Okay, we're down to vocoders now, so pick GSM because it's small and easier to
    00489          translate and sounds pretty good */
    00490       AST_FORMAT_GSM,
    00491       /* iLBC is not too bad */
    00492       AST_FORMAT_ILBC,
    00493       /* Speex is free, but computationally more expensive than GSM */
    00494       AST_FORMAT_SPEEX,
    00495       /* Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
    00496          to use it */
    00497       AST_FORMAT_LPC10,
    00498       /* G.729a is faster than 723 and slightly less expensive */
    00499       AST_FORMAT_G729A,
    00500       /* Down to G.723.1 which is proprietary but at least designed for voice */
    00501       AST_FORMAT_G723_1,
    00502    };
    00503
    00504
    00505    /* Find the first prefered codec in the format given */
    00506    for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
    00507       if (fmts & prefs[x])
    00508          return prefs[x];
    00509    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
    00510    return 0;
    00511 }
    00512
    00513 static const struct ast_channel_tech null_tech = {
    00514    .type = "NULL",
    00515    .description = "Null channel (should not see this)",
    00516 };
    00517
    00518 /*--- ast_channel_alloc: Create a new channel structure */
    00519 struct ast_channel *ast_channel_alloc(int needqueue)
    00520 {
    00521    struct ast_channel *tmp;
    00522    int x;
    00523    int flags;
    00524    struct varshead *headp;
    00525
    00526
    00527    /* If shutting down, don't allocate any new channels */
    00528    if (shutting_down) {
    00529       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
    00530       return NULL;
    00531    }
    00532
    00533    tmp = malloc(sizeof(struct ast_channel));
    00534    if (!tmp) {
    00535       ast_log(LOG_WARNING, "Channel allocation failed: Out of memory\n");
    00536       return NULL;
    00537    }
    00538
    00539    memset(tmp, 0, sizeof(struct ast_channel));
    00540    tmp->sched = sched_context_create();
    00541    if (!tmp->sched) {
    00542       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
    00543       free(tmp);
    00544       return NULL;
    00545    }
    00546
    00547    for (x=0; x<AST_MAX_FDS - 1; x++)
    00548       tmp->fds[x] = -1;
    00549
    00550 #ifdef ZAPTEL_OPTIMIZATIONS
    00551    tmp->timingfd = open("/dev/zap/timer", O_RDWR);
    00552    if (tmp->timingfd > -1) {
    00553       /* Check if timing interface supports new
    00554          ping/pong scheme */
    00555       flags = 1;
    00556       if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
    00557          needqueue = 0;
    00558    }
    00559 #else
    00560    tmp->timingfd = -1;
    00561 #endif
    00562
    00563    if (needqueue) {
    00564       if (pipe(tmp->alertpipe)) {
    00565          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
    00566          free(tmp);
    00567          return NULL;
    00568       } else {
    00569          flags = fcntl(tmp->alertpipe[0], F_GETFL);
    00570          fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
    00571          flags = fcntl(tmp->alertpipe[1], F_GETFL);
    00572          fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
    00573       }
    00574    } else
    00575       /* Make sure we've got it done right if they don't */
    00576       tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
    00577
    00578    /* Always watch the alertpipe */
    00579    tmp->fds[AST_MAX_FDS-1] = tmp->alertpipe[0];
    00580    /* And timing pipe */
    00581    tmp->fds[AST_MAX_FDS-2] = tmp->timingfd;
    00582    strcpy(tmp->name, "**Unknown**");
    00583    /* Initial state */
    00584    tmp->_state = AST_STATE_DOWN;
    00585    tmp->streamid = -1;
    00586    tmp->appl = NULL;
    00587    tmp->data = NULL;
    00588    tmp->fin = global_fin;
    00589    tmp->fout = global_fout;
    00590    ast_mutex_lock(&uniquelock);
    00591    snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++);
    00592    ast_mutex_unlock(&uniquelock);
    00593    headp = &tmp->varshead;
    00594    ast_mutex_init(&tmp->lock);
    00595    AST_LIST_HEAD_INIT_NOLOCK(headp);
    00596    strcpy(tmp->context, "default");
    00597    ast_copy_string(tmp->language, defaultlanguage, sizeof(tmp->language));
    00598    strcpy(tmp->exten, "s");
    00599    tmp->priority = 1;
    00600    tmp->amaflags = ast_default_amaflags;
    00601    ast_copy_string(tmp->accountcode, ast_default_accountcode, sizeof(tmp->accountcode));
    00602
    00603    tmp->tech = &null_tech;
    00604
    00605    ast_mutex_lock(&chlock);
    00606    tmp->next = channels;
    00607    channels = tmp;
    00608
    00609    ast_mutex_unlock(&chlock);
    00610    return tmp;
    00611 }
    00612
    00613 /*--- ast_queue_frame: Queue an outgoing media frame */
    00614 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
    00615 {
    00616    struct ast_frame *f;
    00617    struct ast_frame *prev, *cur;
    00618    int blah = 1;
    00619    int qlen = 0;
    00620
    00621    /* Build us a copy and free the original one */
    00622    f = ast_frdup(fin);
    00623    if (!f) {
    00624       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
    00625       return -1;
    00626    }
    00627    ast_mutex_lock(&chan->lock);
    00628    prev = NULL;
    00629    cur = chan->readq;
    00630    while(cur) {
    00631       if ((cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
    00632          /* Don't bother actually queueing anything after a hangup */
    00633          ast_frfree(f);
    00634          ast_mutex_unlock(&chan->lock);
    00635          return 0;
    00636       }
    00637       prev = cur;
    00638       cur = cur->next;
    00639       qlen++;
    00640    }
    00641    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
    00642    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
    00643       if (fin->frametype != AST_FRAME_VOICE) {
    00644          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
    00645          CRASH;
    00646       } else {
    00647          ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
    00648          ast_frfree(f);
    00649          ast_mutex_unlock(&chan->lock);
    00650          return 0;
    00651       }
    00652    }
    00653    if (prev)
    00654       prev->next = f;
    00655    else
    00656       chan->readq = f;
    00657    if (chan->alertpipe[1] > -1) {
    00658       if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
    00659          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
    00660             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
    00661 #ifdef ZAPTEL_OPTIMIZATIONS
    00662    } else if (chan->timingfd > -1) {
    00663       ioctl(chan->timingfd, ZT_TIMERPING, &blah);
    00664 #endif
    00665    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
    00666       pthread_kill(chan->blocker, SIGURG);
    00667    }
    00668    ast_mutex_unlock(&chan->lock);
    00669    return 0;
    00670 }
    00671
    00672 /*--- ast_queue_hangup: Queue a hangup frame for channel */
    00673 int ast_queue_hangup(struct ast_channel *chan)
    00674 {
    00675    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
    00676    /* Yeah, let's not change a lock-critical value without locking */
    00677    if (!ast_mutex_trylock(&chan->lock)) {
    00678       chan->_softhangup |= AST_SOFTHANGUP_DEV;
    00679       ast_mutex_unlock(&chan->lock);
    00680    }
    00681    return ast_queue_frame(chan, &f);
    00682 }
    00683
    00684 /*--- ast_queue_control: Queue a control frame */
    00685 int ast_queue_control(struct ast_channel *chan, int control)
    00686 {
    00687    struct ast_frame f = { AST_FRAME_CONTROL, };
    00688    f.subclass = control;
    00689    return ast_queue_frame(chan, &f);
    00690 }
    00691
    00692 /*--- ast_channel_defer_dtmf: Set defer DTMF flag on channel */
    00693 int ast_channel_defer_dtmf(struct ast_channel *chan)
    00694 {
    00695    int pre = 0;
    00696
    00697    if (chan) {
    00698       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
    00699       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
    00700    }
    00701    return pre;
    00702 }
    00703
    00704 /*--- ast_channel_undefer_dtmf: Unset defer DTMF flag on channel */
    00705 void ast_channel_undefer_dtmf(struct ast_channel *chan)
    00706 {
    00707    if (chan)
    00708       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
    00709 }
    00710
    00711 /*
    00712  * Helper function to find channels. It supports these modes:
    00713  *
    00714  * prev != NULL : get channel next in list after prev
    00715  * name != NULL : get channel with matching name
    00716  * name != NULL && namelen != 0 : get channel whose name starts with prefix
    00717  * exten != NULL : get channel whose exten or macroexten matches
    00718  * context != NULL && exten != NULL : get channel whose context or macrocontext
    00719  *
    00720  * It returns with the channel's lock held. If getting the individual lock fails,
    00721  * unlock and retry quickly up to 10 times, then give up.
    00722  *
    00723  * XXX Note that this code has cost O(N) because of the need to verify
    00724  * that the object is still on the global list.
    00725  *
    00726  * XXX also note that accessing fields (e.g. c->name in ast_log())
    00727  * can only be done with the lock held or someone could delete the
    00728  * object while we work on it. This causes some ugliness in the code.
    00729  * Note that removing the first ast_log() may be harmful, as it would
    00730  * shorten the retry period and possibly cause failures.
    00731  * We should definitely go for a better scheme that is deadlock-free.
    00732  */
    00733 static struct ast_channel *channel_find_locked(const struct ast_channel *prev,
    00734                       const char *name, const int namelen,
    00735                       const char *context, const char *exten)
    00736 {
    00737    const char *msg = prev ? "deadlock" : "initial deadlock";
    00738    int retries;
    00739    struct ast_channel *c;
    00740
    00741    for (retries = 0; retries < 10; retries++) {
    00742       int done;
    00743
    00744       ast_mutex_lock(&chlock);
    00745       for (c = channels; c; c = c->next) {
    00746          if (prev) { /* look for next item */
    00747             if (c != prev) /* not this one */
    00748                continue;
    00749             /* found, prepare to return c->next */
    00750             if ((c = c->next) == NULL) break;
    00751             /* If prev was the last item on the channel list, then we just
    00752              * want to return NULL, instead of trying to deref NULL in the
    00753              * next section.
    00754              */
    00755          }
    00756          if (name) { /* want match by name */
    00757             if ((!namelen && strcasecmp(c->name, name)) ||
    00758                 (namelen && strncasecmp(c->name, name, namelen)))
    00759                continue;   /* name match failed */
    00760          } else if (exten) {
    00761             if (context && strcasecmp(c->context, context) &&
    00762                 strcasecmp(c->macrocontext, context))
    00763                continue;   /* context match failed */
    00764             if (strcasecmp(c->exten, exten) &&
    00765                 strcasecmp(c->macroexten, exten))
    00766                continue;   /* exten match failed */
    00767          }
    00768          /* if we get here, c points to the desired record */
    00769          break;
    00770       }
    00771       /* exit if chan not found or mutex acquired successfully */
    00772       done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0);
    00773       /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
    00774       if (!done && c) {
    00775          ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name);
    00776          if (retries == 9) {
    00777             /* We are about to fail due to a deadlock, so report this
    00778              * while we still have the list lock.
    00779              */
    00780             ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n", msg, c, retries);
    00781             /* As we have deadlocked, we will skip this channel and see if
    00782              * there is another match.
    00783              * NOTE: No point doing this for a full-name match, as there
    00784              * can be no more matches.
    00785              */
    00786             if (!(name && !namelen)) {
    00787                prev = c;
    00788                retries = -1;
    00789             }
    00790          }
    00791       }
    00792       ast_mutex_unlock(&chlock);
    00793       if (done)
    00794          return c;
    00795       usleep(1);
    00796    }
    00797
    00798    return NULL;
    00799 }
    00800
    00801 /*--- ast_channel_walk_locked: Browse channels in use */
    00802 struct ast_channel *ast_channel_walk_locked(const struct ast_channel *prev)
    00803 {
    00804    return channel_find_locked(prev, NULL, 0, NULL, NULL);
    00805 }
    00806
    00807 /*--- ast_get_channel_by_name_locked: Get channel by name and lock it */
    00808 struct ast_channel *ast_get_channel_by_name_locked(const char *name)
    00809 {
    00810    return channel_find_locked(NULL, name, 0, NULL, NULL);
    00811 }
    00812
    00813 /*--- ast_get_channel_by_name_prefix_locked: Get channel by name prefix and lock it */
    00814 struct ast_channel *ast_get_channel_by_name_prefix_locked(const char *name, const int namelen)
    00815 {
    00816    return channel_find_locked(NULL, name, namelen, NULL, NULL);
    00817 }
    00818
    00819 /*--- ast_walk_channel_by_name_prefix_locked: Get next channel by name prefix and lock it */
    00820 struct ast_channel *ast_walk_channel_by_name_prefix_locked(struct ast_channel *chan, const char *name, const int namelen)
    00821 {
    00822    return channel_find_locked(chan, name, namelen, NULL, NULL);
    00823 }
    00824
    00825 /*--- ast_get_channel_by_exten_locked: Get channel by exten (and optionally context) and lock it */
    00826 struct ast_channel *ast_get_channel_by_exten_locked(const char *exten, const char *context)
    00827 {
    00828    return channel_find_locked(NULL, NULL, 0, context, exten);
    00829 }
    00830
    00831 /*--- ast_safe_sleep_conditional: Wait, look for hangups and condition arg */
    00832 int ast_safe_sleep_conditional(  struct ast_channel *chan, int ms,
    00833    int (*cond)(void*), void *data )
    00834 {
    00835    struct ast_frame *f;
    00836
    00837    while(ms > 0) {
    00838       if( cond && ((*cond)(data) == 0 ) )
    00839          return 0;
    00840       ms = ast_waitfor(chan, ms);
    00841       if (ms <0)
    00842          return -1;
    00843       if (ms > 0) {
    00844          f = ast_read(chan);
    00845          if (!f)
    00846             return -1;
    00847          ast_frfree(f);
    00848       }
    00849    }
    00850    return 0;
    00851 }
    00852
    00853 /*--- ast_safe_sleep: Wait, look for hangups */
    00854 int ast_safe_sleep(struct ast_channel *chan, int ms)
    00855 {
    00856    struct ast_frame *f;
    00857    while(ms > 0) {
    00858       ms = ast_waitfor(chan, ms);
    00859       if (ms <0)
    00860          return -1;
    00861       if (ms > 0) {
    00862          f = ast_read(chan);
    00863          if (!f)
    00864             return -1;
    00865          ast_frfree(f);
    00866       }
    00867    }
    00868    return 0;
    00869 }
    00870
    00871 static void free_cid(struct ast_callerid *cid)
    00872 {
    00873    if (cid->cid_dnid)
    00874       free(cid->cid_dnid);
    00875    if (cid->cid_num)
    00876       free(cid->cid_num);
    00877    if (cid->cid_name)
    00878       free(cid->cid_name);
    00879    if (cid->cid_ani)
    00880       free(cid->cid_ani);
    00881    if (cid->cid_rdnis)
    00882       free(cid->cid_rdnis);
    00883 }
    00884
    00885 /*--- ast_channel_free: Free a channel structure */
    00886 void ast_channel_free(struct ast_channel *chan)
    00887 {
    00888    struct ast_channel *last=NULL, *cur;
    00889    int fd;
    00890    struct ast_var_t *vardata;
    00891    struct ast_frame *f, *fp;
    00892    struct varshead *headp;
    00893    char name[AST_CHANNEL_NAME];
    00894
    00895    headp=&chan->varshead;
    00896
    00897    ast_mutex_lock(&chlock);
    00898    cur = channels;
    00899    while(cur) {
    00900       if (cur == chan) {
    00901          if (last)
    00902             last->next = cur->next;
    00903          else
    00904             channels = cur->next;
    00905          break;
    00906       }
    00907       last = cur;
    00908       cur = cur->next;
    00909    }
    00910    if (!cur) {
    00911       ast_mutex_unlock(&chlock);
    00912       ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
    00913       return;
    00914    }
    00915
    00916    /* Lock and unlock the channel just to be sure nobody
    00917       has it locked still */
    00918    ast_mutex_lock(&cur->lock);
    00919    ast_mutex_unlock(&cur->lock);
    00920    if (chan->tech_pvt) {
    00921       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
    00922       free(chan->tech_pvt);
    00923    }
    00924
    00925    if (chan->sched)
    00926       sched_context_destroy(chan->sched);
    00927
    00928    ast_copy_string(name, chan->name, sizeof(name));
    00929
    00930    /* Stop monitoring */
    00931    if (chan->monitor) {
    00932       chan->monitor->stop( chan, 0 );
    00933    }
    00934
    00935    /* If there is native format music-on-hold state, free it */
    00936    if(chan->music_state)
    00937       ast_moh_cleanup(chan);
    00938
    00939    /* Free translatosr */
    00940    if (chan->readtrans)
    00941       ast_translator_free_path(chan->readtrans);
    00942    if (chan->writetrans)
    00943       ast_translator_free_path(chan->writetrans);
    00944    if (chan->pbx)
    00945       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
    00946    free_cid(&chan->cid);
    00947    ast_mutex_destroy(&chan->lock);
    00948    /* Close pipes if appropriate */
    00949    if ((fd = chan->alertpipe[0]) > -1)
    00950       close(fd);
    00951    if ((fd = chan->alertpipe[1]) > -1)
    00952       close(fd);
    00953    if ((fd = chan->timingfd) > -1)
    00954       close(fd);
    00955    f = chan->readq;
    00956    chan->readq = NULL;
    00957    while(f) {
    00958       fp = f;
    00959       f = f->next;
    00960       ast_frfree(fp);
    00961    }
    00962
    00963    /* loop over the variables list, freeing all data and deleting list items */
    00964    /* no need to lock the list, as the channel is already locked */
    00965
    00966    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
    00967       ast_var_delete(vardata);
    00968
    00969    /* Drop out of the group counting radar */
    00970    ast_app_group_discard(chan);
    00971
    00972    free(chan);
    00973    ast_mutex_unlock(&chlock);
    00974
    00975    ast_device_state_changed_literal(name);
    00976 }
    00977
    00978 int ast_channel_spy_add(struct ast_channel *chan, struct ast_channel_spy *spy)
    00979 {
    00980    /* Link the owner channel to the spy */
    00981    spy->chan = chan;
    00982
    00983    if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) {
    00984       ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n",
    00985          spy->type, chan->name);
    00986       return -1;
    00987    }
    00988
    00989    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) {
    00990       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
    00991          ast_getformatname(spy->read_queue.format));
    00992       return -1;
    00993    }
    00994
    00995    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) {
    00996       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
    00997          ast_getformatname(spy->write_queue.format));
    00998       return -1;
    00999    }
    01000
    01001    if (ast_test_flag(spy, CHANSPY_MIXAUDIO) &&
    01002        ((spy->read_queue.format != AST_FORMAT_SLINEAR) ||
    01003         (spy->write_queue.format != AST_FORMAT_SLINEAR))) {
    01004       ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n",
    01005          ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format));
    01006       return -1;
    01007    }
    01008
    01009    if (!chan->spies) {
    01010       if (!(chan->spies = calloc(1, sizeof(*chan->spies)))) {
    01011          ast_log(LOG_WARNING, "Memory allocation failure\n");
    01012          return -1;
    01013       }
    01014
    01015       AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list);
    01016       AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list);
    01017    } else {
    01018       AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list);
    01019    }
    01020
    01021    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
    01022       ast_cond_init(&spy->trigger, NULL);
    01023       ast_set_flag(spy, CHANSPY_TRIGGER_READ);
    01024       ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
    01025    }
    01026
    01027    ast_log(LOG_DEBUG, "Spy %s added to channel %s\n",
    01028       spy->type, chan->name);
    01029
    01030    return 0;
    01031 }
    01032
    01033 /* Clean up a channel's spy information */
    01034 static void spy_cleanup(struct ast_channel *chan)
    01035 {
    01036    if (AST_LIST_FIRST(&chan->spies->list))
    01037       return;
    01038    if (chan->spies->read_translator.path)
    01039       ast_translator_free_path(chan->spies->read_translator.path);
    01040    if (chan->spies->write_translator.path)
    01041       ast_translator_free_path(chan->spies->write_translator.path);
    01042    free(chan->spies);
    01043    chan->spies = NULL;
    01044    return;
    01045 }
    01046
    01047 /* Detach a spy from it's channel */
    01048 static void spy_detach(struct ast_channel_spy *spy, struct ast_channel *chan)
    01049 {
    01050    /* We only need to poke them if they aren't already done */
    01051    if (spy->status != CHANSPY_DONE) {
    01052       ast_mutex_lock(&spy->lock);
    01053       spy->status = CHANSPY_STOP;
    01054       spy->chan = NULL;
    01055       if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
    01056          ast_cond_signal(&spy->trigger);
    01057       ast_mutex_unlock(&spy->lock);
    01058    }
    01059
    01060    /* Print it out while we still have a lock so the structure can't go away (if signalled above) */
    01061    ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
    01062
    01063    return;
    01064 }
    01065
    01066 void ast_channel_spy_stop_by_type(struct ast_channel *chan, const char *type)
    01067 {
    01068    struct ast_channel_spy *spy = NULL;
    01069
    01070    if (!chan->spies)
    01071       return;
    01072
    01073    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
    01074       if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
    01075          AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
    01076          spy_detach(spy, chan);
    01077       }
    01078    }
    01079    AST_LIST_TRAVERSE_SAFE_END
    01080    spy_cleanup(chan);
    01081 }
    01082
    01083 void ast_channel_spy_trigger_wait(struct ast_channel_spy *spy)
    01084 {
    01085    struct timeval tv;
    01086    struct timespec ts;
    01087
    01088    tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
    01089    ts.tv_sec = tv.tv_sec;
    01090    ts.tv_nsec = tv.tv_usec * 1000;
    01091
    01092    ast_cond_timedwait(&spy->trigger, &spy->lock, &ts);
    01093 }
    01094
    01095 void ast_channel_spy_remove(struct ast_channel *chan, struct ast_channel_spy *spy)
    01096 {
    01097    if (!chan->spies)
    01098       return;
    01099
    01100    AST_LIST_REMOVE(&chan->spies->list, spy, list);
    01101
    01102    spy_detach(spy, chan);
    01103    spy_cleanup(chan);
    01104 }
    01105
    01106 void ast_channel_spy_free(struct ast_channel_spy *spy)
    01107 {
    01108    struct ast_frame *f = NULL;
    01109
    01110    if (spy->status == CHANSPY_DONE)
    01111       return;
    01112
    01113    /* Switch status to done in case we get called twice */
    01114    spy->status = CHANSPY_DONE;
    01115
    01116    /* Drop any frames in the queue */
    01117    for (f = spy->write_queue.head; f; f = spy->write_queue.head) {
    01118       spy->write_queue.head = f->next;
    01119       ast_frfree(f);
    01120    }
    01121    for (f = spy->read_queue.head; f; f= spy->read_queue.head) {
    01122       spy->read_queue.head = f->next;
    01123       ast_frfree(f);
    01124    }
    01125
    01126    /* Destroy the condition if in use */
    01127    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
    01128       ast_cond_destroy(&spy->trigger);
    01129
    01130    /* Destroy our mutex since it is no longer in use */
    01131    ast_mutex_destroy(&spy->lock);
    01132
    01133    return;
    01134 }
    01135
    01136 static void detach_spies(struct ast_channel *chan)
    01137 {
    01138    struct ast_channel_spy *spy = NULL;
    01139
    01140    if (!chan->spies)
    01141       return;
    01142
    01143    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
    01144       AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
    01145       spy_detach(spy, chan);
    01146    }
    01147    AST_LIST_TRAVERSE_SAFE_END
    01148
    01149    spy_cleanup(chan);
    01150 }
    01151
    01152 /*--- ast_softhangup_nolock: Softly hangup a channel, don't lock */
    01153 int ast_softhangup_nolock(struct ast_channel *chan, int cause)
    01154 {
    01155    int res = 0;
    01156    struct ast_frame f = { AST_FRAME_NULL };
    01157    if (option_debug)
    01158       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
    01159    /* Inform channel driver that we need to be hung up, if it cares */
    01160    chan->_softhangup |= cause;
    01161    ast_queue_frame(chan, &f);
    01162    /* Interrupt any poll call or such */
    01163    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
    01164       pthread_kill(chan->blocker, SIGURG);
    01165    return res;
    01166 }
    01167
    01168 /*--- ast_softhangup_nolock: Softly hangup a channel, lock */
    01169 int ast_softhangup(struct ast_channel *chan, int cause)
    01170 {
    01171    int res;
    01172    ast_mutex_lock(&chan->lock);
    01173    res = ast_softhangup_nolock(chan, cause);
    01174    ast_mutex_unlock(&chan->lock);
    01175    return res;
    01176 }
    01177
    01178 enum spy_direction {
    01179    SPY_READ,
    01180    SPY_WRITE,
    01181 };
    01182
    01183 #define SPY_QUEUE_SAMPLE_LIMIT 4000       /* half of one second */
    01184
    01185 static void queue_frame_to_spies(struct ast_channel *chan, struct ast_frame *f, enum spy_direction dir)
    01186 {
    01187    struct ast_frame *translated_frame = NULL;
    01188    struct ast_channel_spy *spy;
    01189    struct ast_channel_spy_queue *queue;
    01190    struct channel_spy_trans *trans;
    01191    struct ast_frame *last;
    01192
    01193    trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator;
    01194
    01195    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
    01196       if (spy->status != CHANSPY_RUNNING)
    01197          continue;
    01198       ast_mutex_lock(&spy->lock);
    01199
    01200       queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue;
    01201
    01202       if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) {
    01203          if (!translated_frame) {
    01204             if (trans->path && (trans->last_format != f->subclass)) {
    01205                ast_translator_free_path(trans->path);
    01206                trans->path = NULL;
    01207             }
    01208             if (!trans->path) {
    01209                ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n",
    01210                   ast_getformatname(f->subclass), chan->name);
    01211                if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
    01212                   ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n",
    01213                      ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR));
    01214                   ast_mutex_unlock(&spy->lock);
    01215                   continue;
    01216                } else {
    01217                   trans->last_format = f->subclass;
    01218                }
    01219             }
    01220             if (!(translated_frame = ast_translate(trans->path, f, 0))) {
    01221                ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n",
    01222                   ast_getformatname(AST_FORMAT_SLINEAR));
    01223                ast_mutex_unlock(&spy->lock);
    01224                break;
    01225             }
    01226          }
    01227
    01228          for (last = queue->head; last && last->next; last = last->next);
    01229          if (last)
    01230             last->next = ast_frdup(translated_frame);
    01231          else
    01232             queue->head = ast_frdup(translated_frame);
    01233       } else {
    01234          if (f->subclass != queue->format) {
    01235             ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n",
    01236                spy->type, chan->name,
    01237                ast_getformatname(queue->format), ast_getformatname(f->subclass));
    01238             ast_mutex_unlock(&spy->lock);
    01239             continue;
    01240          }
    01241
    01242          for (last = queue->head; last && last->next; last = last->next);
    01243          if (last)
    01244             last->next = ast_frdup(f);
    01245          else
    01246             queue->head = ast_frdup(f);
    01247       }
    01248
    01249       queue->samples += f->samples;
    01250
    01251       if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
    01252          if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
    01253             switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
    01254             case CHANSPY_TRIGGER_READ:
    01255                if (dir == SPY_WRITE) {
    01256                   ast_set_flag(spy, CHANSPY_TRIGGER_WRITE);
    01257                   ast_clear_flag(spy, CHANSPY_TRIGGER_READ);
    01258                   if (option_debug)
    01259                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n",
    01260                         spy->type, chan->name);
    01261                }
    01262                break;
    01263             case CHANSPY_TRIGGER_WRITE:
    01264                if (dir == SPY_READ) {
    01265                   ast_set_flag(spy, CHANSPY_TRIGGER_READ);
    01266                   ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
    01267                   if (option_debug)
    01268                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n",
    01269                         spy->type, chan->name);
    01270                }
    01271                break;
    01272             }
    01273             if (option_debug)
    01274                ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n",
    01275                   spy->type, chan->name);
    01276             ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH);
    01277             ast_cond_signal(&spy->trigger);
    01278          } else {
    01279             if (option_debug)
    01280                ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n",
    01281                   spy->type, chan->name, (dir == SPY_READ) ? "read" : "write");
    01282             while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
    01283                struct ast_frame *drop = queue->head;
    01284
    01285                queue->samples -= drop->samples;
    01286                queue->head = drop->next;
    01287                ast_frfree(drop);
    01288             }
    01289          }
    01290       } else {
    01291          switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
    01292          case CHANSPY_TRIGGER_READ:
    01293             if (dir == SPY_READ)
    01294                ast_cond_signal(&spy->trigger);
    01295             break;
    01296          case CHANSPY_TRIGGER_WRITE:
    01297             if (dir == SPY_WRITE)
    01298                ast_cond_signal(&spy->trigger);
    01299             break;
    01300          }
    01301       }
    01302
    01303       ast_mutex_unlock(&spy->lock);
    01304    }
    01305
    01306    if (translated_frame)
    01307       ast_frfree(translated_frame);
    01308 }
    01309
    01310 static void free_translation(struct ast_channel *clone)
    01311 {
    01312    if (clone->writetrans)
    01313       ast_translator_free_path(clone->writetrans);
    01314    if (clone->readtrans)
    01315       ast_translator_free_path(clone->readtrans);
    01316    clone->writetrans = NULL;
    01317    clone->readtrans = NULL;
    01318    clone->rawwriteformat = clone->nativeformats;
    01319    clone->rawreadformat = clone->nativeformats;
    01320 }
    01321
    01322 /*--- ast_hangup: Hangup a channel */
    01323 int ast_hangup(struct ast_channel *chan)
    01324 {
    01325    int res = 0;
    01326    struct ast_cdr *cdr = NULL;
    01327
    01328    /* Don't actually hang up a channel that will masquerade as someone else, or
    01329       if someone is going to masquerade as us */
    01330    ast_mutex_lock(&chan->lock);
    01331
    01332    detach_spies(chan);     /* get rid of spies */
    01333
    01334    if (chan->masq) {
    01335       if (ast_do_masquerade(chan))
    01336          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
    01337    }
    01338
    01339    if (chan->masq) {
    01340       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
    01341       ast_mutex_unlock(&chan->lock);
    01342       return 0;
    01343    }
    01344    /* If this channel is one which will be masqueraded into something,
    01345       mark it as a zombie already, so we know to free it later */
    01346    if (chan->masqr) {
    01347       ast_set_flag(chan, AST_FLAG_ZOMBIE);
    01348       ast_mutex_unlock(&chan->lock);
    01349       return 0;
    01350    }
    01351    free_translation(chan);
    01352    /* Close audio stream */
    01353    if (chan->stream) {
    01354       ast_closestream(chan->stream);
    01355       chan->stream = NULL;
    01356    }
    01357    /* Close video stream */
    01358    if (chan->vstream) {
    01359       ast_closestream(chan->vstream);
    01360       chan->vstream = NULL;
    01361    }
    01362    if (chan->sched) {
    01363       sched_context_destroy(chan->sched);
    01364       chan->sched = NULL;
    01365    }
    01366
    01367    if (chan->generatordata)   /* Clear any tone stuff remaining */
    01368       chan->generator->release(chan, chan->generatordata);
    01369    chan->generatordata = NULL;
    01370    chan->generator = NULL;
    01371    if (chan->cdr) {     /* End the CDR if it hasn't already */
    01372       ast_cdr_end(chan->cdr);
    01373       cdr = chan->cdr;
    01374       chan->cdr = NULL;
    01375    }
    01376    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
    01377       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
    01378                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
    01379                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
    01380       CRASH;
    01381    }
    01382    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
    01383       if (option_debug)
    01384          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
    01385       if (chan->tech->hangup)
    01386          res = chan->tech->hangup(chan);
    01387    } else {
    01388       if (option_debug)
    01389          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
    01390    }
    01391
    01392    ast_mutex_unlock(&chan->lock);
    01393    manager_event(EVENT_FLAG_CALL, "Hangup",
    01394          "Channel: %s\r\n"
    01395          "Uniqueid: %s\r\n"
    01396          "Cause: %d\r\n"
    01397          "Cause-txt: %s\r\n",
    01398          chan->name,
    01399          chan->uniqueid,
    01400          chan->hangupcause,
    01401          ast_cause2str(chan->hangupcause)
    01402          );
    01403    ast_channel_free(chan);
    01404
    01405    /* Defer CDR processing until later */
    01406    if (cdr)
    01407       ast_cdr_detach(cdr);
    01408
    01409    return res;
    01410 }
    01411
    01412 int ast_answer(struct ast_channel *chan)
    01413 {
    01414    int res = 0;
    01415    ast_mutex_lock(&chan->lock);
    01416    /* Stop if we're a zombie or need a soft hangup */
    01417    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
    01418       ast_mutex_unlock(&chan->lock);
    01419       return -1;
    01420    }
    01421    switch(chan->_state) {
    01422    case AST_STATE_RINGING:
    01423    case AST_STATE_RING:
    01424       if (chan->tech->answer)
    01425          res = chan->tech->answer(chan);
    01426       ast_setstate(chan, AST_STATE_UP);
    01427       if (chan->cdr)
    01428          ast_cdr_answer(chan->cdr);
    01429       ast_mutex_unlock(&chan->lock);
    01430       return res;
    01431       break;
    01432    case AST_STATE_UP:
    01433       if (chan->cdr)
    01434          ast_cdr_answer(chan->cdr);
    01435       break;
    01436    }
    01437    ast_mutex_unlock(&chan->lock);
    01438    return 0;
    01439 }
    01440
    01441
    01442
    01443 void ast_deactivate_generator(struct ast_channel *chan)
    01444 {
    01445    ast_mutex_lock(&chan->lock);
    01446    if (chan->generatordata) {
    01447       if (chan->generator && chan->generator->release)
    01448          chan->generator->release(chan, chan->generatordata);
    01449       chan->generatordata = NULL;
    01450       chan->generator = NULL;
    01451       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
    01452       ast_settimeout(chan, 0, NULL, NULL);
    01453    }
    01454    ast_mutex_unlock(&chan->lock);
    01455 }
    01456
    01457 static int generator_force(void *data)
    01458 {
    01459    /* Called if generator doesn't have data */
    01460    void *tmp;
    01461    int res;
    01462    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
    01463    struct ast_channel *chan = data;
    01464    tmp = chan->generatordata;
    01465    chan->generatordata = NULL;
    01466    generate = chan->generator->generate;
    01467    res = generate(chan, tmp, 0, 160);
    01468    chan->generatordata = tmp;
    01469    if (res) {
    01470       ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
    01471       ast_deactivate_generator(chan);
    01472    }
    01473    return 0;
    01474 }
    01475
    01476 int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
    01477 {
    01478    int res = 0;
    01479
    01480    ast_mutex_lock(&chan->lock);
    01481
    01482    if (chan->generatordata) {
    01483       if (chan->generator && chan->generator->release)
    01484          chan->generator->release(chan, chan->generatordata);
    01485       chan->generatordata = NULL;
    01486    }
    01487
    01488    ast_prod(chan);
    01489    if (gen->alloc) {
    01490       if (!(chan->generatordata = gen->alloc(chan, params)))
    01491          res = -1;
    01492    }
    01493
    01494    if (!res) {
    01495       ast_settimeout(chan, 160, generator_force, chan);
    01496       chan->generator = gen;
    01497    }
    01498
    01499    ast_mutex_unlock(&chan->lock);
    01500
    01501    return res;
    01502 }
    01503
    01504 /*--- ast_waitfor_n_fd: Wait for x amount of time on a file descriptor to have input.  */
    01505 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
    01506 {
    01507    struct timeval start = { 0 , 0 };
    01508    int res;
    01509    int x, y;
    01510    int winner = -1;
    01511    int spoint;
    01512    struct pollfd *pfds;
    01513
    01514    pfds = alloca(sizeof(struct pollfd) * n);
    01515    if (!pfds) {
    01516       ast_log(LOG_ERROR, "Out of memory\n");
    01517       return -1;
    01518    }
    01519    if (*ms > 0)
    01520       start = ast_tvnow();
    01521    y = 0;
    01522    for (x=0; x < n; x++) {
    01523       if (fds[x] > -1) {
    01524          pfds[y].fd = fds[x];
    01525          pfds[y].events = POLLIN | POLLPRI;
    01526          y++;
    01527       }
    01528    }
    01529    res = poll(pfds, y, *ms);
    01530    if (res < 0) {
    01531       /* Simulate a timeout if we were interrupted */
    01532       if (errno != EINTR)
    01533          *ms = -1;
    01534       else
    01535          *ms = 0;
    01536       return -1;
    01537    }
    01538    spoint = 0;
    01539    for (x=0; x < n; x++) {
    01540       if (fds[x] > -1) {
    01541          if ((res = ast_fdisset(pfds, fds[x], y, &spoint))) {
    01542             winner = fds[x];
    01543             if (exception) {
    01544                if (res & POLLPRI)
    01545                   *exception = -1;
    01546                else
    01547                   *exception = 0;
    01548             }
    01549          }
    01550       }
    01551    }
    01552    if (*ms > 0) {
    01553       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
    01554       if (*ms < 0)
    01555          *ms = 0;
    01556    }
    01557    return winner;
    01558 }
    01559
    01560 /*--- ast_waitfor_nanfds: Wait for x amount of time on a file descriptor to have input.  */
    01561 struct ast_channel *ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds,
    01562    int *exception, int *outfd, int *ms)
    01563 {
    01564    struct timeval start = { 0 , 0 };
    01565    struct pollfd *pfds;
    01566    int res;
    01567    long rms;
    01568    int x, y, max;
    01569    int spoint;
    01570    time_t now = 0;
    01571    long whentohangup = 0, havewhen = 0, diff;
    01572    struct ast_channel *winner = NULL;
    01573
    01574    pfds = alloca(sizeof(struct pollfd) * (n * AST_MAX_FDS + nfds));
    01575    if (!pfds) {
    01576       ast_log(LOG_ERROR, "Out of memory\n");
    01577       *outfd = -1;
    01578       return NULL;
    01579    }
    01580
    01581    if (outfd)
    01582       *outfd = -99999;
    01583    if (exception)
    01584       *exception = 0;
    01585
    01586    /* Perform any pending masquerades */
    01587    for (x=0; x < n; x++) {
    01588       ast_mutex_lock(&c[x]->lock);
    01589       if (c[x]->whentohangup) {
    01590          if (!havewhen)
    01591             time(&now);
    01592          diff = c[x]->whentohangup - now;
    01593          if (!havewhen || (diff < whentohangup)) {
    01594             havewhen++;
    01595             whentohangup = diff;
    01596          }
    01597       }
    01598       if (c[x]->masq) {
    01599          if (ast_do_masquerade(c[x])) {
    01600             ast_log(LOG_WARNING, "Masquerade failed\n");
    01601             *ms = -1;
    01602             ast_mutex_unlock(&c[x]->lock);
    01603             return NULL;
    01604          }
    01605       }
    01606       ast_mutex_unlock(&c[x]->lock);
    01607    }
    01608
    01609    rms = *ms;
    01610
    01611    if (havewhen) {
    01612       if ((*ms < 0) || (whentohangup * 1000 < *ms)) {
    01613          rms =  whentohangup * 1000;
    01614       }
    01615    }
    01616    max = 0;
    01617    for (x=0; x < n; x++) {
    01618       for (y=0; y< AST_MAX_FDS; y++) {
    01619          if (c[x]->fds[y] > -1) {
    01620             pfds[max].fd = c[x]->fds[y];
    01621             pfds[max].events = POLLIN | POLLPRI;
    01622             pfds[max].revents = 0;
    01623             max++;
    01624          }
    01625       }
    01626       CHECK_BLOCKING(c[x]);
    01627    }
    01628    for (x=0; x < nfds; x++) {
    01629       if (fds[x] > -1) {
    01630          pfds[max].fd = fds[x];
    01631          pfds[max].events = POLLIN | POLLPRI;
    01632          pfds[max].revents = 0;
    01633          max++;
    01634       }
    01635    }
    01636    if (*ms > 0)
    01637       start = ast_tvnow();
    01638
    01639    if (sizeof(int) == 4) {
    01640       do {
    01641          int kbrms = rms;
    01642          if (kbrms > 600000)
    01643             kbrms = 600000;
    01644          res = poll(pfds, max, kbrms);
    01645          if (!res)
    01646             rms -= kbrms;
    01647       } while (!res && (rms > 0));
    01648    } else {
    01649       res = poll(pfds, max, rms);
    01650    }
    01651
    01652    if (res < 0) {
    01653       for (x=0; x < n; x++)
    01654          ast_clear_flag(c[x], AST_FLAG_BLOCKING);
    01655       /* Simulate a timeout if we were interrupted */
    01656       if (errno != EINTR)
    01657          *ms = -1;
    01658       else {
    01659          /* Just an interrupt */
    01660 #if 0
    01661          *ms = 0;
    01662 #endif
    01663       }
    01664       return NULL;
    01665         } else {
    01666          /* If no fds signalled, then timeout. So set ms = 0
    01667          since we may not have an exact timeout.
    01668       */
    01669       if (res == 0)
    01670          *ms = 0;
    01671    }
    01672
    01673    if (havewhen)
    01674       time(&now);
    01675    spoint = 0;
    01676    for (x=0; x < n; x++) {
    01677       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
    01678       if (havewhen && c[x]->whentohangup && (now > c[x]->whentohangup)) {
    01679          c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
    01680          if (!winner)
    01681             winner = c[x];
    01682       }
    01683       for (y=0; y < AST_MAX_FDS; y++) {
    01684          if (c[x]->fds[y] > -1) {
    01685             if ((res = ast_fdisset(pfds, c[x]->fds[y], max, &spoint))) {
    01686                if (res & POLLPRI)
    01687                   ast_set_flag(c[x], AST_FLAG_EXCEPTION);
    01688                else
    01689                   ast_clear_flag(c[x], AST_FLAG_EXCEPTION);
    01690                c[x]->fdno = y;
    01691                winner = c[x];
    01692             }
    01693          }
    01694       }
    01695    }
    01696    for (x=0; x < nfds; x++) {
    01697       if (fds[x] > -1) {
    01698          if ((res = ast_fdisset(pfds, fds[x], max, &spoint))) {
    01699             if (outfd)
    01700                *outfd = fds[x];
    01701             if (exception) {
    01702                if (res & POLLPRI)
    01703                   *exception = -1;
    01704                else
    01705                   *exception = 0;
    01706             }
    01707             winner = NULL;
    01708          }
    01709       }
    01710    }
    01711    if (*ms > 0) {
    01712       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
    01713       if (*ms < 0)
    01714          *ms = 0;
    01715    }
    01716    return winner;
    01717 }
    01718
    01719 struct ast_channel *ast_waitfor_n(struct ast_channel **c, int n, int *ms)
    01720 {
    01721    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
    01722 }
    01723
    01724 int ast_waitfor(struct ast_channel *c, int ms)
    01725 {
    01726    struct ast_channel *chan;
    01727    int oldms = ms;
    01728
    01729    chan = ast_waitfor_n(&c, 1, &ms);
    01730    if (ms < 0) {
    01731       if (oldms < 0)
    01732          return 0;
    01733       else
    01734          return -1;
    01735    }
    01736    return ms;
    01737 }
    01738
    01739 int ast_waitfordigit(struct ast_channel *c, int ms)
    01740 {
    01741    /* XXX Should I be merged with waitfordigit_full XXX */
    01742    struct ast_frame *f;
    01743    int result = 0;
    01744
    01745    /* Stop if we're a zombie or need a soft hangup */
    01746    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
    01747       return -1;
    01748
    01749    /* Wait for a digit, no more than ms milliseconds total. */
    01750    while(ms && !result) {
    01751       ms = ast_waitfor(c, ms);
    01752       if (ms < 0) /* Error */
    01753          result = -1;
    01754       else if (ms > 0) {
    01755          /* Read something */
    01756          f = ast_read(c);
    01757          if (f) {
    01758             if (f->frametype == AST_FRAME_DTMF)
    01759                result = f->subclass;
    01760             ast_frfree(f);
    01761          } else
    01762             result = -1;
    01763       }
    01764    }
    01765    return result;
    01766 }
    01767
    01768 int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
    01769 {
    01770    int res = -1;
    01771 #ifdef ZAPTEL_OPTIMIZATIONS
    01772    if (c->timingfd > -1) {
    01773       if (!func) {
    01774          samples = 0;
    01775          data = 0;
    01776       }
    01777       ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
    01778       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
    01779       c->timingfunc = func;
    01780       c->timingdata = data;
    01781    }
    01782 #endif
    01783    return res;
    01784 }
    01785
    01786 int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
    01787 {
    01788    struct ast_frame *f;
    01789    struct ast_channel *rchan;
    01790    int outfd;
    01791    int res;
    01792
    01793    /* Stop if we're a zombie or need a soft hangup */
    01794    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
    01795       return -1;
    01796    /* Wait for a digit, no more than ms milliseconds total. */
    01797    while(ms) {
    01798       errno = 0;
    01799       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
    01800       if ((!rchan) && (outfd < 0) && (ms)) {
    01801          if (errno == 0 || errno == EINTR)
    01802             continue;
    01803          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
    01804          return -1;
    01805       } else if (outfd > -1) {
    01806          /* The FD we were watching has something waiting */
    01807          return 1;
    01808       } else if (rchan) {
    01809          f = ast_read(c);
    01810          if(!f) {
    01811             return -1;
    01812          }
    01813
    01814          switch(f->frametype) {
    01815          case AST_FRAME_DTMF:
    01816             res = f->subclass;
    01817             ast_frfree(f);
    01818             return res;
    01819          case AST_FRAME_CONTROL:
    01820             switch(f->subclass) {
    01821             case AST_CONTROL_HANGUP:
    01822                ast_frfree(f);
    01823                return -1;
    01824             case AST_CONTROL_RINGING:
    01825             case AST_CONTROL_ANSWER:
    01826                /* Unimportant */
    01827                break;
    01828             default:
    01829                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
    01830                break;
    01831             }
    01832             break;
    01833          case AST_FRAME_VOICE:
    01834             /* Write audio if appropriate */
    01835             if (audiofd > -1)
    01836                write(audiofd, f->data, f->datalen);
    01837          }
    01838          /* Ignore */
    01839          ast_frfree(f);
    01840       }
    01841    }
    01842    return 0; /* Time is up */
    01843 }
    01844
    01845 struct ast_frame *ast_read(struct ast_channel *chan)
    01846 {
    01847    struct ast_frame *f = NULL;
    01848    int blah;
    01849    int prestate;
    01850 #ifdef ZAPTEL_OPTIMIZATIONS
    01851    int (*func)(void *);
    01852    void *data;
    01853    int res;
    01854 #endif
    01855    static struct ast_frame null_frame = {
    01856       AST_FRAME_NULL,
    01857    };
    01858
    01859    ast_mutex_lock(&chan->lock);
    01860    if (chan->masq) {
    01861       if (ast_do_masquerade(chan)) {
    01862          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
    01863          f = NULL;
    01864       } else
    01865          f =  &null_frame;
    01866       ast_mutex_unlock(&chan->lock);
    01867       return f;
    01868    }
    01869
    01870    /* Stop if we're a zombie or need a soft hangup */
    01871    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
    01872       if (chan->generator)
    01873          ast_deactivate_generator(chan);
    01874       ast_mutex_unlock(&chan->lock);
    01875       return NULL;
    01876    }
    01877    prestate = chan->_state;
    01878
    01879    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && !ast_strlen_zero(chan->dtmfq)) {
    01880       /* We have DTMF that has been deferred.  Return it now */
    01881       chan->dtmff.frametype = AST_FRAME_DTMF;
    01882       chan->dtmff.subclass = chan->dtmfq[0];
    01883       /* Drop first digit */
    01884       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
    01885       ast_mutex_unlock(&chan->lock);
    01886       return &chan->dtmff;
    01887    }
    01888
    01889    /* Read and ignore anything on the alertpipe, but read only
    01890       one sizeof(blah) per frame that we send from it */
    01891    if (chan->alertpipe[0] > -1) {
    01892       read(chan->alertpipe[0], &blah, sizeof(blah));
    01893    }
    01894 #ifdef ZAPTEL_OPTIMIZATIONS
    01895    if ((chan->timingfd > -1) && (chan->fdno == AST_MAX_FDS - 2) && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
    01896       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
    01897       blah = -1;
    01898       /* IF we can't get event, assume it's an expired as-per the old interface */
    01899       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
    01900       if (res)
    01901          blah = ZT_EVENT_TIMER_EXPIRED;
    01902
    01903       if (blah == ZT_EVENT_TIMER_PING) {
    01904 #if 0
    01905          ast_log(LOG_NOTICE, "Oooh, there's a PING!\n");
    01906 #endif
    01907          if (!chan->readq || !chan->readq->next) {
    01908             /* Acknowledge PONG unless we need it again */
    01909 #if 0
    01910             ast_log(LOG_NOTICE, "Sending a PONG!\n");
    01911 #endif
    01912             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
    01913                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
    01914             }
    01915          }
    01916       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
    01917          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
    01918          func = chan->timingfunc;
    01919          data = chan->timingdata;
    01920          ast_mutex_unlock(&chan->lock);
    01921          if (func) {
    01922 #if 0
    01923             ast_log(LOG_DEBUG, "Calling private function\n");
    01924 #endif
    01925             func(data);
    01926          } else {
    01927             blah = 0;
    01928             ast_mutex_lock(&chan->lock);
    01929             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
    01930             chan->timingdata = NULL;
    01931             ast_mutex_unlock(&chan->lock);
    01932          }
    01933          f =  &null_frame;
    01934          return f;
    01935       } else
    01936          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
    01937    }
    01938 #endif
    01939    /* Check for pending read queue */
    01940    if (chan->readq) {
    01941       f = chan->readq;
    01942       chan->readq = f->next;
    01943       /* Interpret hangup and return NULL */
    01944       if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
    01945          ast_frfree(f);
    01946          f = NULL;
    01947       }
    01948    } else {
    01949       chan->blocker = pthread_self();
    01950       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
    01951          if (chan->tech->exception)
    01952             f = chan->tech->exception(chan);
    01953          else {
    01954             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
    01955             f = &null_frame;
    01956          }
    01957          /* Clear the exception flag */
    01958          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
    01959       } else {
    01960          if (chan->tech->read)
    01961             f = chan->tech->read(chan);
    01962          else
    01963             ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
    01964       }
    01965    }
    01966
    01967
    01968    if (f && (f->frametype == AST_FRAME_VOICE)) {
    01969       if (!(f->subclass & chan->nativeformats)) {
    01970          /* This frame can't be from the current native formats -- drop it on the
    01971             floor */
    01972          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));
    01973          ast_frfree(f);
    01974          f = &null_frame;
    01975       } else {
    01976          if (chan->spies)
    01977             queue_frame_to_spies(chan, f, SPY_READ);
    01978
    01979          if (chan->monitor && chan->monitor->read_stream ) {
    01980 #ifndef MONITOR_CONSTANT_DELAY
    01981             int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
    01982             if (jump >= 0) {
    01983                jump = chan->outsmpl - chan->insmpl;
    01984                if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
    01985                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
    01986                chan->insmpl += jump + f->samples;
    01987             } else
    01988                chan->insmpl+= f->samples;
    01989 #else
    01990             int jump = chan->outsmpl - chan->insmpl;
    01991             if (jump - MONITOR_DELAY >= 0) {
    01992                if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
    01993                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
    01994                chan->insmpl += jump;
    01995             } else
    01996                chan->insmpl += f->samples;
    01997 #endif
    01998             if (ast_writestream(chan->monitor->read_stream, f) < 0)
    01999                ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
    02000          }
    02001          if (chan->readtrans) {
    02002             f = ast_translate(chan->readtrans, f, 1);
    02003             if (!f)
    02004                f = &null_frame;
    02005          }
    02006       }
    02007    }
    02008
    02009    /* Make sure we always return NULL in the future */
    02010    if (!f) {
    02011       chan->_softhangup |= AST_SOFTHANGUP_DEV;
    02012       if (chan->generator)
    02013          ast_deactivate_generator(chan);
    02014       /* End the CDR if appropriate */
    02015       if (chan->cdr)
    02016          ast_cdr_end(chan->cdr);
    02017    } else if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) && f->frametype == AST_FRAME_DTMF) {
    02018       if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
    02019          chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
    02020       else
    02021          ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
    02022       ast_frfree(f);
    02023       f = &null_frame;
    02024    } else if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_ANSWER)) {
    02025       if (prestate == AST_STATE_UP) {
    02026          ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
    02027          ast_frfree(f);
    02028          f = &null_frame;
    02029       }
    02030       /* Answer the CDR */
    02031       ast_setstate(chan, AST_STATE_UP);
    02032       ast_cdr_answer(chan->cdr);
    02033    }
    02034
    02035    /* Run any generator sitting on the line */
    02036    if (f && (f->frametype == AST_FRAME_VOICE) && chan->generatordata) {
    02037       /* Mask generator data temporarily and apply.  If there is a timing function, it
    02038          will be calling the generator instead */
    02039       void *tmp;
    02040       int res;
    02041       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
    02042
    02043       if (chan->timingfunc) {
    02044          ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
    02045          ast_settimeout(chan, 0, NULL, NULL);
    02046       }
    02047       tmp = chan->generatordata;
    02048       chan->generatordata = NULL;
    02049       generate = chan->generator->generate;
    02050       res = generate(chan, tmp, f->datalen, f->samples);
    02051       chan->generatordata = tmp;
    02052       if (res) {
    02053          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
    02054          ast_deactivate_generator(chan);
    02055       }
    02056    } else if (f && (f->frametype == AST_FRAME_CNG)) {
    02057       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
    02058          ast_log(LOG_DEBUG, "Generator got CNG, switching to zap timed mode\n");
    02059          ast_settimeout(chan, 160, generator_force, chan);
    02060       }
    02061    }
    02062    /* High bit prints debugging */
    02063    if (chan->fin & 0x80000000)
    02064       ast_frame_dump(chan->name, f, "<<");
    02065    if ((chan->fin & 0x7fffffff) == 0x7fffffff)
    02066       chan->fin &= 0x80000000;
    02067    else
    02068       chan->fin++;
    02069    ast_mutex_unlock(&chan->lock);
    02070    return f;
    02071 }
    02072
    02073 int ast_indicate(struct ast_channel *chan, int condition)
    02074 {
    02075    int res = -1;
    02076
    02077    ast_mutex_lock(&chan->lock);
    02078    /* Stop if we're a zombie or need a soft hangup */
    02079    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
    02080       ast_mutex_unlock(&chan->lock);
    02081       return -1;
    02082    }
    02083    if (chan->tech->indicate)
    02084       res = chan->tech->indicate(chan, condition);
    02085    ast_mutex_unlock(&chan->lock);
    02086    if (!chan->tech->indicate || res) {
    02087       /*
    02088        * Device does not support (that) indication, lets fake
    02089        * it by doing our own tone generation. (PM2002)
    02090        */
    02091       if (condition >= 0) {
    02092          const struct tone_zone_sound *ts = NULL;
    02093          switch (condition) {
    02094          case AST_CONTROL_RINGING:
    02095             ts = ast_get_indication_tone(chan->zone, "ring");
    02096             break;
    02097          case AST_CONTROL_BUSY:
    02098             ts = ast_get_indication_tone(chan->zone, "busy");
    02099             break;
    02100          case AST_CONTROL_CONGESTION:
    02101             ts = ast_get_indication_tone(chan->zone, "congestion");
    02102             break;
    02103          }
    02104          if (ts && ts->data[0]) {
    02105             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
    02106             ast_playtones_start(chan,0,ts->data, 1);
    02107             res = 0;
    02108          } else if (condition == AST_CONTROL_PROGRESS) {
    02109             /* ast_playtones_stop(chan); */
    02110          } else if (condition == AST_CONTROL_PROCEEDING) {
    02111             /* Do nothing, really */
    02112          } else if (condition == AST_CONTROL_HOLD) {
    02113             /* Do nothing.... */
    02114          } else if (condition == AST_CONTROL_UNHOLD) {
    02115             /* Do nothing.... */
    02116          } else if (condition == AST_CONTROL_VIDUPDATE) {
    02117             /* Do nothing.... */
    02118          } else {
    02119             /* not handled */
    02120             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
    02121             res = -1;
    02122          }
    02123       }
    02124       else ast_playtones_stop(chan);
    02125    }
    02126    return res;
    02127 }
    02128
    02129 int ast_recvchar(struct ast_channel *chan, int timeout)
    02130 {
    02131    int c;
    02132    char *buf = ast_recvtext(chan, timeout);
    02133    if (buf == NULL)
    02134       return -1;  /* error or timeout */
    02135    c = *(unsigned char *)buf;
    02136    free(buf);
    02137    return c;
    02138 }
    02139
    02140 char *ast_recvtext(struct ast_channel *chan, int timeout)
    02141 {
    02142    int res, done = 0;
    02143    char *buf = NULL;
    02144
    02145    while (!done) {
    02146       struct ast_frame *f;
    02147       if (ast_check_hangup(chan))
    02148          break;
    02149       res = ast_waitfor(chan, timeout);
    02150       if (res <= 0) /* timeout or error */
    02151          break;
    02152       timeout = res; /* update timeout */
    02153       f = ast_read(chan);
    02154       if (f == NULL)
    02155          break; /* no frame */
    02156       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
    02157          done = 1;   /* force a break */
    02158       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
    02159          buf = strndup((char *) f->data, f->datalen); /* dup and break */
    02160          done = 1;
    02161       }
    02162       ast_frfree(f);
    02163    }
    02164    return buf;
    02165 }
    02166
    02167 int ast_sendtext(struct ast_channel *chan, const char *text)
    02168 {
    02169    int res = 0;
    02170    /* Stop if we're a zombie or need a soft hangup */
    02171    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
    02172       return -1;
    02173    CHECK_BLOCKING(chan);
    02174    if (chan->tech->send_text)
    02175       res = chan->tech->send_text(chan, text);
    02176    ast_clear_flag(chan, AST_FLAG_BLOCKING);
    02177    return res;
    02178 }
    02179
    02180 static int do_senddigit(struct ast_channel *chan, char digit)
    02181 {
    02182    int res = -1;
    02183
    02184    if (chan->tech->send_digit)
    02185       res = chan->tech->send_digit(chan, digit);
    02186    if (!chan->tech->send_digit || res) {
    02187       /*
    02188        * Device does not support DTMF tones, lets fake
    02189        * it by doing our own generation. (PM2002)
    02190        */
    02191       static const char* dtmf_tones[] = {
    02192          "!941+1336/100,!0/100", /* 0 */
    02193          "!697+1209/100,!0/100", /* 1 */
    02194          "!697+1336/100,!0/100", /* 2 */
    02195          "!697+1477/100,!0/100", /* 3 */
    02196          "!770+1209/100,!0/100", /* 4 */
    02197          "!770+1336/100,!0/100", /* 5 */
    02198          "!770+1477/100,!0/100", /* 6 */
    02199          "!852+1209/100,!0/100", /* 7 */
    02200          "!852+1336/100,!0/100", /* 8 */
    02201          "!852+1477/100,!0/100", /* 9 */
    02202          "!697+1633/100,!0/100", /* A */
    02203          "!770+1633/100,!0/100", /* B */
    02204          "!852+1633/100,!0/100", /* C */
    02205          "!941+1633/100,!0/100", /* D */
    02206          "!941+1209/100,!0/100", /* * */
    02207          "!941+1477/100,!0/100" };  /* # */
    02208       if (digit >= '0' && digit <='9')
    02209          ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
    02210       else if (digit >= 'A' && digit <= 'D')
    02211          ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
    02212       else if (digit == '*')
    02213          ast_playtones_start(chan, 0, dtmf_tones[14], 0);
    02214       else if (digit == '#')
    02215          ast_playtones_start(chan, 0, dtmf_tones[15], 0);
    02216       else {
    02217          /* not handled */
    02218          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
    02219       }
    02220    }
    02221    return 0;
    02222 }
    02223
    02224 int ast_senddigit(struct ast_channel *chan, char digit)
    02225 {
    02226    return do_senddigit(chan, digit);
    02227 }
    02228
    02229 int ast_prod(struct ast_channel *chan)
    02230 {
    02231    struct ast_frame a = { AST_FRAME_VOICE };
    02232    char nothing[128];
    02233
    02234    /* Send an empty audio frame to get things moving */
    02235    if (chan->_state != AST_STATE_UP) {
    02236       ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
    02237       a.subclass = chan->rawwriteformat;
    02238       a.data = nothing + AST_FRIENDLY_OFFSET;
    02239       a.src = "ast_prod";
    02240       if (ast_write(chan, &a))
    02241          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
    02242    }
    02243    return 0;
    02244 }
    02245
    02246 int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
    02247 {
    02248    int res;
    02249    if (!chan->tech->write_video)
    02250       return 0;
    02251    res = ast_write(chan, fr);
    02252    if (!res)
    02253       res = 1;
    02254    return res;
    02255 }
    02256
    02257 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
    02258 {
    02259    int res = -1;
    02260    struct ast_frame *f = NULL;
    02261    /* Stop if we're a zombie or need a soft hangup */
    02262    ast_mutex_lock(&chan->lock);
    02263    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))  {
    02264       ast_mutex_unlock(&chan->lock);
    02265       return -1;
    02266    }
    02267    /* Handle any pending masquerades */
    02268    if (chan->masq) {
    02269       if (ast_do_masquerade(chan)) {
    02270          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
    02271          ast_mutex_unlock(&chan->lock);
    02272          return -1;
    02273       }
    02274    }
    02275    if (chan->masqr) {
    02276       ast_mutex_unlock(&chan->lock);
    02277       return 0;
    02278    }
    02279    if (chan->generatordata) {
    02280       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
    02281          ast_deactivate_generator(chan);
    02282       else {
    02283          ast_mutex_unlock(&chan->lock);
    02284          return 0;
    02285       }
    02286    }
    02287    /* High bit prints debugging */
    02288    if (chan->fout & 0x80000000)
    02289       ast_frame_dump(chan->name, fr, ">>");
    02290    CHECK_BLOCKING(chan);
    02291    switch(fr->frametype) {
    02292    case AST_FRAME_CONTROL:
    02293       /* XXX Interpret control frames XXX */
    02294       ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
    02295       break;
    02296    case AST_FRAME_DTMF:
    02297       ast_clear_flag(chan, AST_FLAG_BLOCKING);
    02298       ast_mutex_unlock(&chan->lock);
    02299       res = do_senddigit(chan,fr->subclass);
    02300       ast_mutex_lock(&chan->lock);
    02301       CHECK_BLOCKING(chan);
    02302       break;
    02303    case AST_FRAME_TEXT:
    02304       if (chan->tech->send_text)
    02305          res = chan->tech->send_text(chan, (char *) fr->data);
    02306       else
    02307          res = 0;
    02308       break;
    02309    case AST_FRAME_HTML:
    02310       if (chan->tech->send_html)
    02311          res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
    02312       else
    02313          res = 0;
    02314       break;
    02315    case AST_FRAME_VIDEO:
    02316       /* XXX Handle translation of video codecs one day XXX */
    02317       if (chan->tech->write_video)
    02318          res = chan->tech->write_video(chan, fr);
    02319       else
    02320          res = 0;
    02321       break;
    02322    case AST_FRAME_NULL:
    02323    case AST_FRAME_IAX:
    02324       /* Ignore these */
    02325       res = 0;
    02326       break;
    02327    default:
    02328       if (chan->tech->write) {
    02329          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
    02330          if (f) {
    02331             if (f->frametype == AST_FRAME_VOICE && chan->spies)
    02332                queue_frame_to_spies(chan, f, SPY_WRITE);
    02333
    02334             if( chan->monitor && chan->monitor->write_stream &&
    02335                   f && ( f->frametype == AST_FRAME_VOICE ) ) {
    02336 #ifndef MONITOR_CONSTANT_DELAY
    02337                int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
    02338                if (jump >= 0) {
    02339                   jump = chan->insmpl - chan->outsmpl;
    02340                   if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
    02341                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
    02342                   chan->outsmpl += jump + f->samples;
    02343                } else
    02344                   chan->outsmpl += f->samples;
    02345 #else
    02346                int jump = chan->insmpl - chan->outsmpl;
    02347                if (jump - MONITOR_DELAY >= 0) {
    02348                   if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
    02349                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
    02350                   chan->outsmpl += jump;
    02351                } else
    02352                   chan->outsmpl += f->samples;
    02353 #endif
    02354                if (ast_writestream(chan->monitor->write_stream, f) < 0)
    02355                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
    02356             }
    02357
    02358             res = chan->tech->write(chan, f);
    02359          } else
    02360             res = 0;
    02361       }
    02362    }
    02363
    02364    /* It's possible this is a translated frame */
    02365    if (f && f->frametype == AST_FRAME_DTMF) {
    02366       ast_log(LOG_DTMF, "%s : %c\n", chan->name, f->subclass);
    02367    } else if (fr->frametype == AST_FRAME_DTMF) {
    02368       ast_log(LOG_DTMF, "%s : %c\n", chan->name, fr->subclass);
    02369    }
    02370
    02371    if (f && (f != fr))
    02372       ast_frfree(f);
    02373    ast_clear_flag(chan, AST_FLAG_BLOCKING);
    02374    /* Consider a write failure to force a soft hangup */
    02375    if (res < 0)
    02376       chan->_softhangup |= AST_SOFTHANGUP_DEV;
    02377    else {
    02378       if ((chan->fout & 0x7fffffff) == 0x7fffffff)
    02379          chan->fout &= 0x80000000;
    02380       else
    02381          chan->fout++;
    02382    }
    02383    ast_mutex_unlock(&chan->lock);
    02384    return res;
    02385 }
    02386
    02387 static int set_format(struct ast_channel *chan, int fmt, int *rawformat, int *format,
    02388             struct ast_trans_pvt **trans, const int direction)
    02389 {
    02390    int native;
    02391    int res;
    02392
    02393    native = chan->nativeformats;
    02394    /* Find a translation path from the native format to one of the desired formats */
    02395    if (!direction)
    02396       /* reading */
    02397       res = ast_translator_best_choice(&fmt, &native);
    02398    else
    02399       /* writing */
    02400       res = ast_translator_best_choice(&native, &fmt);
    02401
    02402    if (res < 0) {
    02403       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
    02404          ast_getformatname(native), ast_getformatname(fmt));
    02405       return -1;
    02406    }
    02407
    02408    /* Now we have a good choice for both. */
    02409    ast_mutex_lock(&chan->lock);
    02410
    02411    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
    02412       /* the channel is already in these formats, so nothing to do */
    02413       ast_mutex_unlock(&chan->lock);
    02414       return 0;
    02415    }
    02416
    02417    *rawformat = native;
    02418    /* User perspective is fmt */
    02419    *format = fmt;
    02420    /* Free any read translation we have right now */
    02421    if (*trans)
    02422       ast_translator_free_path(*trans);
    02423    /* Build a translation path from the raw format to the desired format */
    02424    if (!direction)
    02425       /* reading */
    02426       *trans = ast_translator_build_path(*format, *rawformat);
    02427    else
    02428       /* writing */
    02429       *trans = ast_translator_build_path(*rawformat, *format);
    02430    ast_mutex_unlock(&chan->lock);
    02431    if (option_debug)
    02432       ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
    02433          direction ? "write" : "read", ast_getformatname(fmt));
    02434    return 0;
    02435 }
    02436
    02437 int ast_set_read_format(struct ast_channel *chan, int fmt)
    02438 {
    02439    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
    02440            &chan->readtrans, 0);
    02441 }
    02442
    02443 int ast_set_write_format(struct ast_channel *chan, int fmt)
    02444 {
    02445    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
    02446            &chan->writetrans, 1);
    02447 }
    02448
    02449 struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
    02450 {
    02451    int state = 0;
    02452    int cause = 0;
    02453    struct ast_channel *chan;
    02454    struct ast_frame *f;
    02455    int res = 0;
    02456
    02457    chan = ast_request(type, format, data, &cause);
    02458    if (chan) {
    02459       if (oh) {
    02460          if (oh->vars)
    02461             ast_set_variables(chan, oh->vars);
    02462          if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name)
    02463             ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
    02464          if (oh->parent_channel)
    02465             ast_channel_inherit_variables(oh->parent_channel, chan);
    02466          if (oh->account)
    02467             ast_cdr_setaccount(chan, oh->account);
    02468       }
    02469       ast_set_callerid(chan, cid_num, cid_name, cid_num);
    02470
    02471       if (!ast_call(chan, data, 0)) {
    02472          res = 1; /* in case chan->_state is already AST_STATE_UP */
    02473          while (timeout && (chan->_state != AST_STATE_UP)) {
    02474             res = ast_waitfor(chan, timeout);
    02475             if (res < 0) {
    02476                /* Something not cool, or timed out */
    02477                break;
    02478             }
    02479             /* If done, break out */
    02480             if (!res)
    02481                break;
    02482             if (timeout > -1)
    02483                timeout = res;
    02484             f = ast_read(chan);
    02485             if (!f) {
    02486                state = AST_CONTROL_HANGUP;
    02487                res = 0;
    02488                break;
    02489             }
    02490             if (f->frametype == AST_FRAME_CONTROL) {
    02491                if (f->subclass == AST_CONTROL_RINGING)
    02492                   state = AST_CONTROL_RINGING;
    02493                else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
    02494                   state = f->subclass;
    02495                   ast_frfree(f);
    02496                   break;
    02497                } else if (f->subclass == AST_CONTROL_ANSWER) {
    02498                   state = f->subclass;
    02499                   ast_frfree(f);
    02500                   break;
    02501                } else if (f->subclass == AST_CONTROL_PROGRESS || f->subclass == AST_CONTROL_PROCEEDING) {
    02502                   /* Ignore */
    02503                } else if (f->subclass == -1) {
    02504                   /* Ignore -- just stopping indications */
    02505                } else {
    02506                   ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
    02507                }
    02508             }
    02509             ast_frfree(f);
    02510          }
    02511       } else
    02512          ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
    02513    } else {
    02514       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
    02515       switch(cause) {
    02516       case AST_CAUSE_BUSY:
    02517          state = AST_CONTROL_BUSY;
    02518          break;
    02519       case AST_CAUSE_CONGESTION:
    02520          state = AST_CONTROL_CONGESTION;
    02521          break;
    02522       }
    02523    }
    02524    if (chan) {
    02525       /* Final fixups */
    02526       if (oh) {
    02527          if (oh->context && *oh->context)
    02528             ast_copy_string(chan->context, oh->context, sizeof(chan->context));
    02529          if (oh->exten && *oh->exten)
    02530             ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
    02531          if (oh->priority)
    02532             chan->priority = oh->priority;
    02533       }
    02534       if (chan->_state == AST_STATE_UP)
    02535          state = AST_CONTROL_ANSWER;
    02536    }
    02537    if (outstate)
    02538       *outstate = state;
    02539    if (chan && res <= 0) {
    02540       if (!chan->cdr) {
    02541          chan->cdr = ast_cdr_alloc();
    02542          if (chan->cdr)
    02543             ast_cdr_init(chan->cdr, chan);
    02544       }
    02545       if (chan->cdr) {
    02546          char tmp[256];
    02547          snprintf(tmp, 256, "%s/%s", type, (char *)data);
    02548          ast_cdr_setapp(chan->cdr,"Dial",tmp);
    02549          ast_cdr_update(chan);
    02550          ast_cdr_start(chan->cdr);
    02551          ast_cdr_end(chan->cdr);
    02552          /* If the cause wasn't handled properly */
    02553          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
    02554             ast_cdr_failed(chan->cdr);
    02555       } else
    02556          ast_log(LOG_WARNING, "Unable to create Call Detail Record\n");
    02557       ast_hangup(chan);
    02558       chan = NULL;
    02559    }
    02560    return chan;
    02561 }
    02562
    02563 struct ast_channel *ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
    02564 {
    02565    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
    02566 }
    02567
    02568 struct ast_channel *ast_request(const char *type, int format, void *data, int *cause)
    02569 {
    02570    struct chanlist *chan;
    02571    struct ast_channel *c;
    02572    int capabilities;
    02573    int fmt;
    02574    int res;
    02575    int foo;
    02576
    02577    if (!cause)
    02578       cause = &foo;
    02579    *cause = AST_CAUSE_NOTDEFINED;
    02580
    02581    if (ast_mutex_lock(&chlock)) {
    02582       ast_log(LOG_WARNING, "Unable to lock channel list\n");
    02583       return NULL;
    02584    }
    02585
    02586    for (chan = backends; chan; chan = chan->next) {
    02587       if (strcasecmp(type, chan->tech->type))
    02588          continue;
    02589
    02590       capabilities = chan->tech->capabilities;
    02591       fmt = format;
    02592       res = ast_translator_best_choice(&fmt, &capabilities);
    02593       if (res < 0) {
    02594          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
    02595          ast_mutex_unlock(&chlock);
    02596          return NULL;
    02597       }
    02598       ast_mutex_unlock(&chlock);
    02599       if (!chan->tech->requester)
    02600          return NULL;
    02601
    02602       if (!(c = chan->tech->requester(type, capabilities, data, cause)))
    02603          return NULL;
    02604
    02605       if (c->_state == AST_STATE_DOWN) {
    02606          manager_event(EVENT_FLAG_CALL, "Newchannel",
    02607                   "Channel: %s\r\n"
    02608                   "State: %s\r\n"
    02609                   "CallerID: %s\r\n"
    02610                   "CallerIDName: %s\r\n"
    02611                   "Uniqueid: %s\r\n",
    02612                   c->name, ast_state2str(c->_state),
    02613                   c->cid.cid_num ? c->cid.cid_num : "<unknown>",
    02614                   c->cid.cid_name ? c->cid.cid_name : "<unknown>",
    02615                   c->uniqueid);
    02616          ast_set_flag(c, AST_FLAG_NOTNEW);
    02617       }
    02618       return c;
    02619    }
    02620
    02621    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
    02622    *cause = AST_CAUSE_NOSUCHDRIVER;
    02623    ast_mutex_unlock(&chlock);
    02624
    02625    return NULL;
    02626 }
    02627
    02628 int ast_call(struct ast_channel *chan, char *addr, int timeout)
    02629 {
    02630    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
    02631       If the remote end does not answer within the timeout, then do NOT hang up, but
    02632       return anyway.  */
    02633    int res = -1;
    02634    /* Stop if we're a zombie or need a soft hangup */
    02635    ast_mutex_lock(&chan->lock);
    02636    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan))
    02637       if (chan->tech->call)
    02638          res = chan->tech->call(chan, addr, timeout);
    02639    ast_mutex_unlock(&chan->lock);
    02640    return res;
    02641 }
    02642
    02643 /*--- ast_transfer: Transfer a call to dest, if the channel supports transfer */
    02644 /* called by app_transfer or the manager interface */
    02645 int ast_transfer(struct ast_channel *chan, char *dest)
    02646 {
    02647    int res = -1;
    02648
    02649    /* Stop if we're a zombie or need a soft hangup */
    02650    ast_mutex_lock(&chan->lock);
    02651    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
    02652       if (chan->tech->transfer) {
    02653          res = chan->tech->transfer(chan, dest);
    02654          if (!res)
    02655             res = 1;
    02656       } else
    02657          res = 0;
    02658    }
    02659    ast_mutex_unlock(&chan->lock);
    02660    return res;
    02661 }
    02662
    02663 int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
    02664 {
    02665    int pos=0;
    02666    int to = ftimeout;
    02667    int d;
    02668
    02669    /* XXX Merge with full version? XXX */
    02670    /* Stop if we're a zombie or need a soft hangup */
    02671    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
    02672       return -1;
    02673    if (!len)
    02674       return -1;
    02675    do {
    02676       if (c->stream) {
    02677          d = ast_waitstream(c, AST_DIGIT_ANY);
    02678          ast_stopstream(c);
    02679          usleep(1000);
    02680          if (!d)
    02681             d = ast_waitfordigit(c, to);
    02682       } else {
    02683          d = ast_waitfordigit(c, to);
    02684       }
    02685       if (d < 0)
    02686          return -1;
    02687       if (d == 0) {
    02688          s[pos]='\0';
    02689          return 1;
    02690       }
    02691       if (!strchr(enders, d))
    02692          s[pos++] = d;
    02693       if (strchr(enders, d) || (pos >= len)) {
    02694          s[pos]='\0';
    02695          return 0;
    02696       }
    02697       to = timeout;
    02698    } while(1);
    02699    /* Never reached */
    02700    return 0;
    02701 }
    02702
    02703 int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
    02704 {
    02705    int pos=0;
    02706    int to = ftimeout;
    02707    int d;
    02708
    02709    /* Stop if we're a zombie or need a soft hangup */
    02710    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
    02711       return -1;
    02712    if (!len)
    02713       return -1;
    02714    do {
    02715       if (c->stream) {
    02716          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
    02717          ast_stopstream(c);
    02718          usleep(1000);
    02719          if (!d)
    02720             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
    02721       } else {
    02722          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
    02723       }
    02724       if (d < 0)
    02725          return -1;
    02726       if (d == 0) {
    02727          s[pos]='\0';
    02728          return 1;
    02729       }
    02730       if (d == 1) {
    02731          s[pos]='\0';
    02732          return 2;
    02733       }
    02734       if (!strchr(enders, d))
    02735          s[pos++] = d;
    02736       if (strchr(enders, d) || (pos >= len)) {
    02737          s[pos]='\0';
    02738          return 0;
    02739       }
    02740       to = timeout;
    02741    } while(1);
    02742    /* Never reached */
    02743    return 0;
    02744 }
    02745
    02746 int ast_channel_supports_html(struct ast_channel *chan)
    02747 {
    02748    if (chan->tech->send_html)
    02749       return 1;
    02750    return 0;
    02751 }
    02752
    02753 int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
    02754 {
    02755    if (chan->tech->send_html)
    02756       return chan->tech->send_html(chan, subclass, data, datalen);
    02757    return -1;
    02758 }
    02759
    02760 int ast_channel_sendurl(struct ast_channel *chan, const char *url)
    02761 {
    02762    if (chan->tech->send_html)
    02763       return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
    02764    return -1;
    02765 }
    02766
    02767 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
    02768 {
    02769    int src;
    02770    int dst;
    02771
    02772    if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
    02773       /* Already compatible!  Moving on ... */
    02774       return 0;
    02775    }
    02776
    02777    /* Set up translation from the chan to the peer */
    02778    src = chan->nativeformats;
    02779    dst = peer->nativeformats;
    02780    if (ast_translator_best_choice(&dst, &src) < 0) {
    02781       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
    02782       return -1;
    02783    }
    02784
    02785    /* if the best path is not 'pass through', then
    02786       transcoding is needed; if desired, force transcode path
    02787       to use SLINEAR between channels */
    02788    if ((src != dst) && option_transcode_slin)
    02789       dst = AST_FORMAT_SLINEAR;
    02790    if (ast_set_read_format(chan, dst) < 0) {
    02791       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
    02792       return -1;
    02793    }
    02794    if (ast_set_write_format(peer, dst) < 0) {
    02795       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
    02796       return -1;
    02797    }
    02798
    02799    /* Set up translation from the peer to the chan */
    02800    src = peer->nativeformats;
    02801    dst = chan->nativeformats;
    02802    if (ast_translator_best_choice(&dst, &src) < 0) {
    02803       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
    02804       return -1;
    02805    }
    02806    /* if the best path is not 'pass through', then
    02807       transcoding is needed; if desired, force transcode path
    02808       to use SLINEAR between channels */
    02809    if ((src != dst) && option_transcode_slin)
    02810       dst = AST_FORMAT_SLINEAR;
    02811    if (ast_set_read_format(peer, dst) < 0) {
    02812       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
    02813       return -1;
    02814    }
    02815    if (ast_set_write_format(chan, dst) < 0) {
    02816       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
    02817       return -1;
    02818    }
    02819    return 0;
    02820 }
    02821
    02822 int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
    02823 {
    02824    struct ast_frame null = { AST_FRAME_NULL, };
    02825    int res = -1;
    02826    struct ast_channel *final_orig = original, *final_clone = clone;
    02827
    02828    ast_mutex_lock(&original->lock);
    02829    while(ast_mutex_trylock(&clone->lock)) {
    02830       ast_mutex_unlock(&original->lock);
    02831       usleep(1);
    02832       ast_mutex_lock(&original->lock);
    02833    }
    02834
    02835    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
    02836       and if so, we don't really want to masquerade it, but its proxy */
    02837    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
    02838       final_orig = original->_bridge;
    02839
    02840    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
    02841       final_clone = clone->_bridge;
    02842
    02843    if ((final_orig != original) || (final_clone != clone)) {
    02844       ast_mutex_lock(&final_orig->lock);
    02845       while(ast_mutex_trylock(&final_clone->lock)) {
    02846          ast_mutex_unlock(&final_orig->lock);
    02847          usleep(1);
    02848          ast_mutex_lock(&final_orig->lock);
    02849       }
    02850       ast_mutex_unlock(&clone->lock);
    02851       ast_mutex_unlock(&original->lock);
    02852       original = final_orig;
    02853       clone = final_clone;
    02854    }
    02855
    02856    if (original == clone) {
    02857       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
    02858       ast_mutex_unlock(&clone->lock);
    02859       ast_mutex_unlock(&original->lock);
    02860       return -1;
    02861    }
    02862
    02863    ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
    02864       clone->name, original->name);
    02865    if (original->masq) {
    02866       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
    02867          original->masq->name, original->name);
    02868    } else if (clone->masqr) {
    02869       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
    02870          clone->name, clone->masqr->name);
    02871    } else {
    02872       original->masq = clone;
    02873       clone->masqr = original;
    02874       ast_queue_frame(original, &null);
    02875       ast_queue_frame(clone, &null);
    02876       ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
    02877       res = 0;
    02878    }
    02879
    02880    ast_mutex_unlock(&clone->lock);
    02881    ast_mutex_unlock(&original->lock);
    02882
    02883    return res;
    02884 }
    02885
    02886 void ast_change_name(struct ast_channel *chan, char *newname)
    02887 {
    02888    char tmp[256];
    02889    ast_copy_string(tmp, chan->name, sizeof(tmp));
    02890    ast_copy_string(chan->name, newname, sizeof(chan->name));
    02891    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", tmp, chan->name, chan->uniqueid);
    02892 }
    02893
    02894 void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
    02895 {
    02896    struct ast_var_t *current, *newvar;
    02897    char *varname;
    02898
    02899    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
    02900       int vartype = 0;
    02901
    02902       varname = ast_var_full_name(current);
    02903       if (!varname)
    02904          continue;
    02905
    02906       if (varname[0] == '_') {
    02907          vartype = 1;
    02908          if (varname[1] == '_')
    02909             vartype = 2;
    02910       }
    02911
    02912       switch (vartype) {
    02913       case 1:
    02914          newvar = ast_var_assign(&varname[1], ast_var_value(current));
    02915          if (newvar) {
    02916             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
    02917             if (option_debug)
    02918                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
    02919          }
    02920          break;
    02921       case 2:
    02922          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
    02923          if (newvar) {
    02924             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
    02925             if (option_debug)
    02926                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
    02927          }
    02928          break;
    02929       default:
    02930          if (option_debug)
    02931             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
    02932          break;
    02933       }
    02934    }
    02935 }
    02936
    02937 /* Clone channel variables from 'clone' channel into 'original' channel
    02938    All variables except those related to app_groupcount are cloned
    02939    Variables are actually _removed_ from 'clone' channel, presumably
    02940    because it will subsequently be destroyed.
    02941    Assumes locks will be in place on both channels when called.
    02942 */
    02943
    02944 static void clone_variables(struct ast_channel *original, struct ast_channel *clone)
    02945 {
    02946    struct ast_var_t *current, *newvar;
    02947    /* Append variables from clone channel into original channel */
    02948    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
    02949    if (AST_LIST_FIRST(&clone->varshead))
    02950       AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
    02951    AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead);
    02952
    02953    /* then, dup the varshead list into the clone */
    02954
    02955    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
    02956       newvar = ast_var_assign(current->name, current->value);
    02957       if (newvar)
    02958          AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries);
    02959    }
    02960 }
    02961
    02962 /*--- ast_do_masquerade: Masquerade a channel */
    02963 /* Assumes channel will be locked when called */
    02964 int ast_do_masquerade(struct ast_channel *original)
    02965 {
    02966    int x,i;
    02967    int res=0;
    02968    int origstate;
    02969    struct ast_frame *cur, *prev;
    02970    const struct ast_channel_tech *t;
    02971    void *t_pvt;
    02972    struct ast_callerid tmpcid;
    02973    struct ast_channel *clone = original->masq;
    02974    struct ast_channel_spy_list *spy_list;
    02975    struct ast_channel_spy *spy = NULL;
    02976    int rformat = original->readformat;
    02977    int wformat = original->writeformat;
    02978    char newn[100];
    02979    char orig[100];
    02980    char masqn[100];
    02981    char zombn[100];
    02982
    02983    if (option_debug > 3)
    02984       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
    02985          clone->name, clone->_state, original->name, original->_state);
    02986
    02987    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
    02988       the clone channel into the original channel.  Start by killing off the original
    02989       channel's backend.   I'm not sure we're going to keep this function, because
    02990       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
    02991
    02992    /* We need the clone's lock, too */
    02993    ast_mutex_lock(&clone->lock);
    02994
    02995    ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
    02996
    02997    /* Having remembered the original read/write formats, we turn off any translation on either
    02998       one */
    02999    free_translation(clone);
    03000    free_translation(original);
    03001
    03002
    03003    /* Unlink the masquerade */
    03004    original->masq = NULL;
    03005    clone->masqr = NULL;
    03006
    03007    /* Save the original name */
    03008    ast_copy_string(orig, original->name, sizeof(orig));
    03009    /* Save the new name */
    03010    ast_copy_string(newn, clone->name, sizeof(newn));
    03011    /* Create the masq name */
    03012    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
    03013
    03014    /* Copy the name from the clone channel */
    03015    ast_copy_string(original->name, newn, sizeof(original->name));
    03016
    03017    /* Mangle the name of the clone channel */
    03018    ast_copy_string(clone->name, masqn, sizeof(clone->name));
    03019
    03020    /* Notify any managers of the change, first the masq then the other */
    03021    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
    03022    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
    03023
    03024    /* Swap the technlogies */
    03025    t = original->tech;
    03026    original->tech = clone->tech;
    03027    clone->tech = t;
    03028
    03029    t_pvt = original->tech_pvt;
    03030    original->tech_pvt = clone->tech_pvt;
    03031    clone->tech_pvt = t_pvt;
    03032
    03033    /* Swap the readq's */
    03034    cur = original->readq;
    03035    original->readq = clone->readq;
    03036    clone->readq = cur;
    03037
    03038    /* Swap the alertpipes */
    03039    for (i = 0; i < 2; i++) {
    03040       x = original->alertpipe[i];
    03041       original->alertpipe[i] = clone->alertpipe[i];
    03042       clone->alertpipe[i] = x;
    03043    }
    03044
    03045    /* Swap the raw formats */
    03046    x = original->rawreadformat;
    03047    original->rawreadformat = clone->rawreadformat;
    03048    clone->rawreadformat = x;
    03049    x = original->rawwriteformat;
    03050    original->rawwriteformat = clone->rawwriteformat;
    03051    clone->rawwriteformat = x;
    03052
    03053    /* Swap the spies */
    03054    spy_list = original->spies;
    03055    original->spies = clone->spies;
    03056    clone->spies = spy_list;
    03057
    03058    /* Update channel on respective spy lists if present */
    03059    if (original->spies) {
    03060       AST_LIST_TRAVERSE(&original->spies->list, spy, list) {
    03061          ast_mutex_lock(&spy->lock);
    03062          spy->chan = original;
    03063          ast_mutex_unlock(&spy->lock);
    03064       }
    03065    }
    03066    if (clone->spies) {
    03067       AST_LIST_TRAVERSE(&clone->spies->list, spy, list) {
    03068          ast_mutex_lock(&spy->lock);
    03069          spy->chan = clone;
    03070          ast_mutex_unlock(&spy->lock);
    03071       }
    03072    }
    03073
    03074    /* Save any pending frames on both sides.  Start by counting
    03075     * how many we're going to need... */
    03076    prev = NULL;
    03077    cur = clone->readq;
    03078    x = 0;
    03079    while(cur) {
    03080       x++;
    03081       prev = cur;
    03082       cur = cur->next;
    03083    }
    03084    /* If we had any, prepend them to the ones already in the queue, and
    03085     * load up the alertpipe */
    03086    if (prev) {
    03087       prev->next = original->readq;
    03088       original->readq = clone->readq;
    03089       clone->readq = NULL;
    03090       if (original->alertpipe[1] > -1) {
    03091          for (i = 0; i < x; i++)
    03092             write(original->alertpipe[1], &x, sizeof(x));
    03093       }
    03094    }
    03095    clone->_softhangup = AST_SOFTHANGUP_DEV;
    03096
    03097
    03098    /* And of course, so does our current state.  Note we need not
    03099       call ast_setstate since the event manager doesn't really consider
    03100       these separate.  We do this early so that the clone has the proper
    03101       state of the original channel. */
    03102    origstate = original->_state;
    03103    original->_state = clone->_state;
    03104    clone->_state = origstate;
    03105
    03106    if (clone->tech->fixup){
    03107       res = clone->tech->fixup(original, clone);
    03108       if (res)
    03109          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
    03110    }
    03111
    03112    /* Start by disconnecting the original's physical side */
    03113    if (clone->tech->hangup)
    03114       res = clone->tech->hangup(clone);
    03115    if (res) {
    03116       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
    03117       ast_mutex_unlock(&clone->lock);
    03118       return -1;
    03119    }
    03120
    03121    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
    03122    /* Mangle the name of the clone channel */
    03123    ast_copy_string(clone->name, zombn, sizeof(clone->name));
    03124    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
    03125
    03126    /* Update the type. */
    03127    original->type = clone->type;
    03128    t_pvt = original->monitor;
    03129    original->monitor = clone->monitor;
    03130    clone->monitor = t_pvt;
    03131
    03132    /* Keep the same language.  */
    03133    ast_copy_string(original->language, clone->language, sizeof(original->language));
    03134    /* Copy the FD's */
    03135    for (x = 0; x < AST_MAX_FDS; x++) {
    03136       original->fds[x] = clone->fds[x];
    03137    }
    03138    /* Drop group from original */
    03139    ast_app_group_update(clone, original);
    03140    clone_variables(original, clone);
    03141    /* Presense of ADSI capable CPE follows clone */
    03142    original->adsicpe = clone->adsicpe;
    03143    /* Bridge remains the same */
    03144    /* CDR fields remain the same */
    03145    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
    03146    /* Application and data remain the same */
    03147    /* Clone exception  becomes real one, as with fdno */
    03148    ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
    03149    original->fdno = clone->fdno;
    03150    /* Schedule context remains the same */
    03151    /* Stream stuff stays the same */
    03152    /* Keep the original state.  The fixup code will need to work with it most likely */
    03153
    03154    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
    03155       out. */
    03156    tmpcid = original->cid;
    03157    original->cid = clone->cid;
    03158    clone->cid = tmpcid;
    03159
    03160    /* Restore original timing file descriptor */
    03161    original->fds[AST_MAX_FDS - 2] = original->timingfd;
    03162
    03163    /* Our native formats are different now */
    03164    original->nativeformats = clone->nativeformats;
    03165
    03166    /* Context, extension, priority, app data, jump table,  remain the same */
    03167    /* pvt switches.  pbx stays the same, as does next */
    03168
    03169    /* Set the write format */
    03170    ast_set_write_format(original, wformat);
    03171
    03172    /* Set the read format */
    03173    ast_set_read_format(original, rformat);
    03174
    03175    /* Copy the music class */
    03176    ast_copy_string(original->musicclass, clone->musicclass, sizeof(original->musicclass));
    03177
    03178    ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
    03179
    03180    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
    03181       can fix up everything as best as possible */
    03182    if (original->tech->fixup) {
    03183       res = original->tech->fixup(clone, original);
    03184       if (res) {
    03185          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
    03186             original->type, original->name);
    03187          ast_mutex_unlock(&clone->lock);
    03188          return -1;
    03189       }
    03190    } else
    03191       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
    03192          original->type, original->name);
    03193
    03194    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
    03195       a zombie so nothing tries to touch it.  If it's already been marked as a
    03196       zombie, then free it now (since it already is considered invalid). */
    03197    if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
    03198       ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
    03199       ast_mutex_unlock(&clone->lock);
    03200       manager_event(EVENT_FLAG_CALL, "Hangup",
    03201          "Channel: %s\r\n"
    03202          "Uniqueid: %s\r\n"
    03203          "Cause: %d\r\n"
    03204          "Cause-txt: %s\r\n",
    03205          clone->name,
    03206          clone->uniqueid,
    03207          clone->hangupcause,
    03208          ast_cause2str(clone->hangupcause)
    03209          );
    03210       ast_channel_free(clone);
    03211    } else {
    03212       struct ast_frame null_frame = { AST_FRAME_NULL, };
    03213       ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
    03214       ast_set_flag(clone, AST_FLAG_ZOMBIE);
    03215       ast_queue_frame(clone, &null_frame);
    03216       ast_mutex_unlock(&clone->lock);
    03217    }
    03218
    03219    /* Signal any blocker */
    03220    if (ast_test_flag(original, AST_FLAG_BLOCKING))
    03221       pthread_kill(original->blocker, SIGURG);
    03222    ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
    03223    return 0;
    03224 }
    03225
    03226 void ast_set_callerid(struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
    03227 {
    03228    if (callerid) {
    03229       if (chan->cid.cid_num)
    03230          free(chan->cid.cid_num);
    03231       if (ast_strlen_zero(callerid))
    03232          chan->cid.cid_num = NULL;
    03233       else
    03234          chan->cid.cid_num = strdup(callerid);
    03235    }
    03236    if (calleridname) {
    03237       if (chan->cid.cid_name)
    03238          free(chan->cid.cid_name);
    03239       if (ast_strlen_zero(calleridname))
    03240          chan->cid.cid_name = NULL;
    03241       else
    03242          chan->cid.cid_name = strdup(calleridname);
    03243    }
    03244    if (ani) {
    03245       if (chan->cid.cid_ani)
    03246          free(chan->cid.cid_ani);
    03247       if (ast_strlen_zero(ani))
    03248          chan->cid.cid_ani = NULL;
    03249       else
    03250          chan->cid.cid_ani = strdup(ani);
    03251    }
    03252    if (chan->cdr)
    03253       ast_cdr_setcid(chan->cdr, chan);
    03254    manager_event(EVENT_FLAG_CALL, "Newcallerid",
    03255             "Channel: %s\r\n"
    03256             "CallerID: %s\r\n"
    03257             "CallerIDName: %s\r\n"
    03258             "Uniqueid: %s\r\n"
    03259             "CID-CallingPres: %d (%s)\r\n",
    03260             chan->name, chan->cid.cid_num ?
    03261             chan->cid.cid_num : "<Unknown>",
    03262             chan->cid.cid_name ?
    03263             chan->cid.cid_name : "<Unknown>",
    03264             chan->uniqueid,
    03265             chan->cid.cid_pres,
    03266             ast_describe_caller_presentation(chan->cid.cid_pres)
    03267             );
    03268 }
    03269
    03270 int ast_setstate(struct ast_channel *chan, int state)
    03271 {
    03272    int oldstate = chan->_state;
    03273
    03274    if (oldstate == state)
    03275       return 0;
    03276
    03277    chan->_state = state;
    03278    ast_device_state_changed_literal(chan->name);
    03279    manager_event(EVENT_FLAG_CALL,
    03280             (oldstate == AST_STATE_DOWN && !ast_test_flag(chan, AST_FLAG_NOTNEW)) ? "Newchannel" : "Newstate",
    03281             "Channel: %s\r\n"
    03282             "State: %s\r\n"
    03283             "CallerID: %s\r\n"
    03284             "CallerIDName: %s\r\n"
    03285             "Uniqueid: %s\r\n",
    03286             chan->name, ast_state2str(chan->_state),
    03287             chan->cid.cid_num ? chan->cid.cid_num : "<unknown>",
    03288             chan->cid.cid_name ? chan->cid.cid_name : "<unknown>",
    03289             chan->uniqueid);
    03290
    03291    return 0;
    03292 }
    03293
    03294 /*--- Find bridged channel */
    03295 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
    03296 {
    03297    struct ast_channel *bridged;
    03298    bridged = chan->_bridge;
    03299    if (bridged && bridged->tech->bridged_channel)
    03300       bridged = bridged->tech->bridged_channel(chan, bridged);
    03301    return bridged;
    03302 }
    03303
    03304 static void bridge_playfile(struct ast_channel *chan, struct ast_channel *peer, char *sound, int remain)
    03305 {
    03306    int res=0, min=0, sec=0,check=0;
    03307
    03308    check = ast_autoservice_start(peer);
    03309    if(check)
    03310       return;
    03311
    03312    if (remain > 0) {
    03313       if (remain / 60 > 1) {
    03314          min = remain / 60;
    03315          sec = remain % 60;
    03316       } else {
    03317          sec = remain;
    03318       }
    03319    }
    03320
    03321    if (!strcmp(sound,"timeleft")) { /* Queue support */
    03322       res = ast_streamfile(chan, "vm-youhave", chan->language);
    03323       res = ast_waitstream(chan, "");
    03324       if (min) {
    03325          res = ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, (char *) NULL);
    03326          res = ast_streamfile(chan, "queue-minutes", chan->language);
    03327          res = ast_waitstream(chan, "");
    03328       }
    03329       if (sec) {
    03330          res = ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, (char *) NULL);
    03331          res = ast_streamfile(chan, "queue-seconds", chan->language);
    03332          res = ast_waitstream(chan, "");
    03333       }
    03334    } else {
    03335       res = ast_streamfile(chan, sound, chan->language);
    03336       res = ast_waitstream(chan, "");
    03337    }
    03338
    03339    check = ast_autoservice_stop(peer);
    03340 }
    03341
    03342 static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct ast_channel *c1,
    03343                    struct ast_bridge_config *config, struct ast_frame **fo,
    03344                    struct ast_channel **rc, struct timeval bridge_end)
    03345 {
    03346    /* Copy voice back and forth between the two channels. */
    03347    struct ast_channel *cs[3];
    03348    struct ast_frame *f;
    03349    struct ast_channel *who = NULL;
    03350    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
    03351    int o0nativeformats;
    03352    int o1nativeformats;
    03353    int watch_c0_dtmf;
    03354    int watch_c1_dtmf;
    03355    void *pvt0, *pvt1;
    03356    int to;
    03357
    03358    cs[0] = c0;
    03359    cs[1] = c1;
    03360    pvt0 = c0->tech_pvt;
    03361    pvt1 = c1->tech_pvt;
    03362    o0nativeformats = c0->nativeformats;
    03363    o1nativeformats = c1->nativeformats;
    03364    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
    03365    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
    03366
    03367    for (;;) {
    03368       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
    03369           (o0nativeformats != c0->nativeformats) ||
    03370           (o1nativeformats != c1->nativeformats)) {
    03371          /* Check for Masquerade, codec changes, etc */
    03372          res = AST_BRIDGE_RETRY;
    03373          break;
    03374       }
    03375       if (bridge_end.tv_sec) {
    03376          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
    03377          if (to <= 0) {
    03378             if (config->timelimit)
    03379                res = AST_BRIDGE_RETRY;
    03380             else
    03381                res = AST_BRIDGE_COMPLETE;
    03382             break;
    03383          }
    03384       } else
    03385          to = -1;
    03386       who = ast_waitfor_n(cs, 2, &to);
    03387       if (!who) {
    03388          ast_log(LOG_DEBUG, "Nobody there, continuing...\n");
    03389          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
    03390             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
    03391                c0->_softhangup = 0;
    03392             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
    03393                c1->_softhangup = 0;
    03394             c0->_bridge = c1;
    03395             c1->_bridge = c0;
    03396          }
    03397          continue;
    03398       }
    03399       f = ast_read(who);
    03400       if (!f) {
    03401          *fo = NULL;
    03402          *rc = who;
    03403          res = AST_BRIDGE_COMPLETE;
    03404          ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
    03405          break;
    03406       }
    03407
    03408       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
    03409          if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) ||
    03410              (f->subclass == AST_CONTROL_VIDUPDATE)) {
    03411             ast_indicate(who == c0 ? c1 : c0, f->subclass);
    03412          } else {
    03413             *fo = f;
    03414             *rc = who;
    03415             res =  AST_BRIDGE_COMPLETE;
    03416             ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
    03417             break;
    03418          }
    03419       }
    03420       if ((f->frametype == AST_FRAME_VOICE) ||
    03421           (f->frametype == AST_FRAME_DTMF) ||
    03422           (f->frametype == AST_FRAME_VIDEO) ||
    03423           (f->frametype == AST_FRAME_IMAGE) ||
    03424           (f->frametype == AST_FRAME_HTML) ||
    03425           (f->frametype == AST_FRAME_TEXT)) {
    03426          if (f->frametype == AST_FRAME_DTMF) {
    03427             if (((who == c0) && watch_c0_dtmf) ||
    03428                 ((who == c1) && watch_c1_dtmf)) {
    03429                *rc = who;
    03430                *fo = f;
    03431                res = AST_BRIDGE_COMPLETE;
    03432                ast_log(LOG_DEBUG, "Got DTMF on channel (%s)\n", who->name);
    03433                break;
    03434             } else {
    03435                goto tackygoto;
    03436             }
    03437          } else {
    03438 #if 0
    03439             ast_log(LOG_DEBUG, "Read from %s\n", who->name);
    03440             if (who == last)
    03441                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
    03442             last = who;
    03443 #endif
    03444 tackygoto:
    03445             ast_write((who == c0) ? c1 : c0, f);
    03446          }
    03447       }
    03448       ast_frfree(f);
    03449
    03450       /* Swap who gets priority */
    03451       cs[2] = cs[0];
    03452       cs[0] = cs[1];
    03453       cs[1] = cs[2];
    03454    }
    03455    return res;
    03456 }
    03457
    03458 /*--- ast_channel_bridge: Bridge two channels together */
    03459 enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_channel *c1,
    03460                  struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
    03461 {
    03462    struct ast_channel *who = NULL;
    03463    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
    03464    int nativefailed=0;
    03465    int firstpass;
    03466    int o0nativeformats;
    03467    int o1nativeformats;
    03468    long time_left_ms=0;
    03469    struct timeval nexteventts = { 0, };
    03470    char caller_warning = 0;
    03471    char callee_warning = 0;
    03472
    03473    if (c0->_bridge) {
    03474       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
    03475          c0->name, c0->_bridge->name);
    03476       return -1;
    03477    }
    03478    if (c1->_bridge) {
    03479       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
    03480          c1->name, c1->_bridge->name);
    03481       return -1;
    03482    }
    03483
    03484    /* Stop if we're a zombie or need a soft hangup */
    03485    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
    03486        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
    03487       return -1;
    03488
    03489    *fo = NULL;
    03490    firstpass = config->firstpass;
    03491    config->firstpass = 0;
    03492
    03493    if (ast_tvzero(config->start_time))
    03494       config->start_time = ast_tvnow();
    03495    time_left_ms = config->timelimit;
    03496
    03497    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
    03498    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
    03499
    03500    if (config->start_sound && firstpass) {
    03501       if (caller_warning)
    03502          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
    03503       if (callee_warning)
    03504          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
    03505    }
    03506
    03507    /* Keep track of bridge */
    03508    c0->_bridge = c1;
    03509    c1->_bridge = c0;
    03510
    03511    manager_event(EVENT_FLAG_CALL, "Link",
    03512             "Channel1: %s\r\n"
    03513             "Channel2: %s\r\n"
    03514             "Uniqueid1: %s\r\n"
    03515             "Uniqueid2: %s\r\n"
    03516             "CallerID1: %s\r\n"
    03517             "CallerID2: %s\r\n",
    03518             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
    03519
    03520    o0nativeformats = c0->nativeformats;
    03521    o1nativeformats = c1->nativeformats;
    03522
    03523    if (config->feature_timer) {
    03524       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
    03525    } else if (config->timelimit) {
    03526       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
    03527       if (caller_warning || callee_warning)
    03528          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
    03529    }
    03530
    03531    for (/* ever */;;) {
    03532       struct timeval now = { 0, };
    03533       int to;
    03534
    03535       to = -1;
    03536
    03537       if (!ast_tvzero(nexteventts)) {
    03538          now = ast_tvnow();
    03539          to = ast_tvdiff_ms(nexteventts, now);
    03540          if (to <= 0 && !config->timelimit) {
    03541             res = AST_BRIDGE_COMPLETE;
    03542             break;
    03543          }
    03544
    03545       }
    03546
    03547       if (config->timelimit) {
    03548          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
    03549          if (time_left_ms < to)
    03550             to = time_left_ms;
    03551
    03552          if (time_left_ms <= 0) {
    03553             if (caller_warning && config->end_sound)
    03554                bridge_playfile(c0, c1, config->end_sound, 0);
    03555             if (callee_warning && config->end_sound)
    03556                bridge_playfile(c1, c0, config->end_sound, 0);
    03557             *fo = NULL;
    03558             if (who)
    03559                *rc = who;
    03560             res = 0;
    03561             break;
    03562          }
    03563
    03564          if (to <= 0) {
    03565             if (time_left_ms >= 5000) {
    03566                /* force the time left to round up if appropriate */
    03567                if (caller_warning && config->warning_sound && config->play_warning)
    03568                   bridge_playfile(c0, c1, config->warning_sound,
    03569                         (time_left_ms + 500) / 1000);
    03570                if (callee_warning && config->warning_sound && config->play_warning)
    03571                   bridge_playfile(c1, c0, config->warning_sound,
    03572                         (time_left_ms + 500) / 1000);
    03573             }
    03574             if (config->warning_freq) {
    03575                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
    03576             }
    03577
    03578             if ( (!config->warning_freq) ||  ( config->timelimit - ast_tvdiff_ms(nexteventts, config->start_time) < 0)) {
    03579                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
    03580             }
    03581          }
    03582       }
    03583
    03584       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
    03585          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
    03586             c0->_softhangup = 0;
    03587          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
    03588             c1->_softhangup = 0;
    03589          c0->_bridge = c1;
    03590          c1->_bridge = c0;
    03591          ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
    03592          continue;
    03593       }
    03594
    03595       /* Stop if we're a zombie or need a soft hangup */
    03596       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
    03597           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
    03598          *fo = NULL;
    03599          if (who)
    03600             *rc = who;
    03601          res = 0;
    03602          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",
    03603             c0->name, c1->name,
    03604             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
    03605             ast_check_hangup(c0) ? "Yes" : "No",
    03606             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
    03607             ast_check_hangup(c1) ? "Yes" : "No");
    03608          break;
    03609       }
    03610
    03611       /* See if the BRIDGEPEER variable needs to be updated */
    03612       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
    03613          pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
    03614       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
    03615          pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
    03616
    03617       if (c0->tech->bridge &&
    03618           (config->timelimit == 0) &&
    03619           (c0->tech->bridge == c1->tech->bridge) &&
    03620           !nativefailed && !c0->monitor && !c1->monitor &&
    03621           !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
    03622           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) {
    03623          /* Looks like they share a bridge method and nothing else is in the way */
    03624          if (option_verbose > 2)
    03625             ast_verbose(VERBOSE_PREFIX_3 "Attempting native bridge of %s and %s\n", c0->name, c1->name);
    03626          ast_set_flag(c0, AST_FLAG_NBRIDGE);
    03627          ast_set_flag(c1, AST_FLAG_NBRIDGE);
    03628          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
    03629             manager_event(EVENT_FLAG_CALL, "Unlink",
    03630                      "Channel1: %s\r\n"
    03631                      "Channel2: %s\r\n"
    03632                      "Uniqueid1: %s\r\n"
    03633                      "Uniqueid2: %s\r\n"
    03634                      "CallerID1: %s\r\n"
    03635                      "CallerID2: %s\r\n",
    03636                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
    03637             ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
    03638
    03639             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
    03640             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
    03641
    03642             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
    03643                continue;
    03644
    03645             c0->_bridge = NULL;
    03646             c1->_bridge = NULL;
    03647
    03648             return res;
    03649          } else {
    03650             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
    03651             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
    03652          }
    03653          switch (res) {
    03654          case AST_BRIDGE_RETRY:
    03655             continue;
    03656          default:
    03657             ast_log(LOG_WARNING, "Private bridge between %s and %s failed\n", c0->name, c1->name);
    03658             /* fallthrough */
    03659          case AST_BRIDGE_FAILED_NOWARN:
    03660             nativefailed++;
    03661             break;
    03662          }
    03663       }
    03664
    03665       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
    03666           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
    03667           !(c0->generator || c1->generator)) {
    03668          if (ast_channel_make_compatible(c0, c1)) {
    03669             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
    03670                                 manager_event(EVENT_FLAG_CALL, "Unlink",
    03671                      "Channel1: %s\r\n"
    03672                      "Channel2: %s\r\n"
    03673                      "Uniqueid1: %s\r\n"
    03674                      "Uniqueid2: %s\r\n"
    03675                      "CallerID1: %s\r\n"
    03676                      "CallerID2: %s\r\n",
    03677                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
    03678             return AST_BRIDGE_FAILED;
    03679          }
    03680          o0nativeformats = c0->nativeformats;
    03681          o1nativeformats = c1->nativeformats;
    03682       }
    03683       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
    03684       if (res != AST_BRIDGE_RETRY && fo)
    03685          break;
    03686    }
    03687
    03688    c0->_bridge = NULL;
    03689    c1->_bridge = NULL;
    03690
    03691    manager_event(EVENT_FLAG_CALL, "Unlink",
    03692             "Channel1: %s\r\n"
    03693             "Channel2: %s\r\n"
    03694             "Uniqueid1: %s\r\n"
    03695             "Uniqueid2: %s\r\n"
    03696             "CallerID1: %s\r\n"
    03697             "CallerID2: %s\r\n",
    03698             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
    03699    ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
    03700
    03701    return res;
    03702 }
    03703
    03704 /*--- ast_channel_setoption: Sets an option on a channel */
    03705 int ast_channel_setoption(struct ast_channel *chan, int option, void *data, int datalen, int block)
    03706 {
    03707    int res;
    03708
    03709    if (chan->tech->setoption) {
    03710       res = chan->tech->setoption(chan, option, data, datalen);
    03711       if (res < 0)
    03712          return res;
    03713    } else {
    03714       errno = ENOSYS;
    03715       return -1;
    03716    }
    03717    if (block) {
    03718       /* XXX Implement blocking -- just wait for our option frame reply, discarding
    03719          intermediate packets. XXX */
    03720       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
    03721       return -1;
    03722    }
    03723    return 0;
    03724 }
    03725
    03726 struct tonepair_def {
    03727    int freq1;
    03728    int freq2;
    03729    int duration;
    03730    int vol;
    03731 };
    03732
    03733 struct tonepair_state {
    03734    float freq1;
    03735    float freq2;
    03736    float vol;
    03737    int duration;
    03738    int pos;
    03739    int origwfmt;
    03740    struct ast_frame f;
    03741    unsigned char offset[AST_FRIENDLY_OFFSET];
    03742    short data[4000];
    03743 };
    03744
    03745 static void tonepair_release(struct ast_channel *chan, void *params)
    03746 {
    03747    struct tonepair_state *ts = params;
    03748
    03749    if (chan) {
    03750       ast_set_write_format(chan, ts->origwfmt);
    03751    }
    03752    free(ts);
    03753 }
    03754
    03755 static void *tonepair_alloc(struct ast_channel *chan, void *params)
    03756 {
    03757    struct tonepair_state *ts;
    03758    struct tonepair_def *td = params;
    03759
    03760    ts = malloc(sizeof(struct tonepair_state));
    03761    if (!ts)
    03762       return NULL;
    03763    memset(ts, 0, sizeof(struct tonepair_state));
    03764    ts->origwfmt = chan->writeformat;
    03765    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
    03766       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
    03767       tonepair_release(NULL, ts);
    03768       ts = NULL;
    03769    } else {
    03770       ts->freq1 = td->freq1;
    03771       ts->freq2 = td->freq2;
    03772       ts->duration = td->duration;
    03773       ts->vol = td->vol;
    03774    }
    03775    /* Let interrupts interrupt :) */
    03776    ast_set_flag(chan, AST_FLAG_WRITE_INT);
    03777    return ts;
    03778 }
    03779
    03780 static int tonepair_generator(struct ast_channel *chan, void *data, int len, int samples)
    03781 {
    03782    struct tonepair_state *ts = data;
    03783    int x;
    03784
    03785    /* we need to prepare a frame with 16 * timelen samples as we're
    03786     * generating SLIN audio
    03787     */
    03788    len = samples * 2;
    03789
    03790    if (len > sizeof(ts->data) / 2 - 1) {
    03791       ast_log(LOG_WARNING, "Can't generate that much data!\n");
    03792       return -1;
    03793    }
    03794    memset(&ts->f, 0, sizeof(ts->f));
    03795    for (x = 0; x < (len / 2); x++) {
    03796       ts->data[x] = ts->vol * (
    03797             sin((ts->freq1 * 2.0 * M_PI / 8000.0) * (ts->pos + x)) +
    03798             sin((ts->freq2 * 2.0 * M_PI / 8000.0) * (ts->pos + x))
    03799          );
    03800    }
    03801    ts->f.frametype = AST_FRAME_VOICE;
    03802    ts->f.subclass = AST_FORMAT_SLINEAR;
    03803    ts->f.datalen = len;
    03804    ts->f.samples = samples;
    03805    ts->f.offset = AST_FRIENDLY_OFFSET;
    03806    ts->f.data = ts->data;
    03807    ast_write(chan, &ts->f);
    03808    ts->pos += x;
    03809    if (ts->duration > 0) {
    03810       if (ts->pos >= ts->duration * 8)
    03811          return -1;
    03812    }
    03813    return 0;
    03814 }
    03815
    03816 static struct ast_generator tonepair = {
    03817    alloc: tonepair_alloc,
    03818    release: tonepair_release,
    03819    generate: tonepair_generator,
    03820 };
    03821
    03822 int ast_tonepair_start(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
    03823 {
    03824    struct tonepair_def d = { 0, };
    03825
    03826    d.freq1 = freq1;
    03827    d.freq2 = freq2;
    03828    d.duration = duration;
    03829    if (vol < 1)
    03830       d.vol = 8192;
    03831    else
    03832       d.vol = vol;
    03833    if (ast_activate_generator(chan, &tonepair, &d))
    03834       return -1;
    03835    return 0;
    03836 }
    03837
    03838 void ast_tonepair_stop(struct ast_channel *chan)
    03839 {
    03840    ast_deactivate_generator(chan);
    03841 }
    03842
    03843 int ast_tonepair(struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
    03844 {
    03845    struct ast_frame *f;
    03846    int res;
    03847
    03848    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
    03849       return res;
    03850
    03851    /* Give us some wiggle room */
    03852    while(chan->generatordata && (ast_waitfor(chan, 100) >= 0)) {
    03853       f = ast_read(chan);
    03854       if (f)
    03855          ast_frfree(f);
    03856       else
    03857          return -1;
    03858    }
    03859    return 0;
    03860 }
    03861
    03862 ast_group_t ast_get_group(char *s)
    03863 {
    03864    char *copy;
    03865    char *piece;
    03866    char *c=NULL;
    03867    int start=0, finish=0, x;
    03868    ast_group_t group = 0;
    03869
    03870    copy = ast_strdupa(s);
    03871    if (!copy) {
    03872       ast_log(LOG_ERROR, "Out of memory\n");
    03873       return 0;
    03874    }
    03875    c = copy;
    03876
    03877    while((piece = strsep(&c, ","))) {
    03878       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
    03879          /* Range */
    03880       } else if (sscanf(piece, "%30d", &start)) {
    03881          /* Just one */
    03882          finish = start;
    03883       } else {
    03884          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
    03885          continue;
    03886       }
    03887       for (x = start; x <= finish; x++) {
    03888          if ((x > 63) || (x < 0)) {
    03889             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
    03890          } else
    03891             group |= ((ast_group_t) 1 << x);
    03892       }
    03893    }
    03894    return group;
    03895 }
    03896
    03897 static int (*ast_moh_start_ptr)(struct ast_channel *, char *) = NULL;
    03898 static void (*ast_moh_stop_ptr)(struct ast_channel *) = NULL;
    03899 static void (*ast_moh_cleanup_ptr)(struct ast_channel *) = NULL;
    03900
    03901
    03902 void ast_install_music_functions(int (*start_ptr)(struct ast_channel *, char *),
    03903                          void (*stop_ptr)(struct ast_channel *),
    03904                          void (*cleanup_ptr)(struct ast_channel *)
    03905                          )
    03906 {
    03907    ast_moh_start_ptr = start_ptr;
    03908    ast_moh_stop_ptr = stop_ptr;
    03909    ast_moh_cleanup_ptr = cleanup_ptr;
    03910 }
    03911
    03912 void ast_uninstall_music_functions(void)
    03913 {
    03914    ast_moh_start_ptr = NULL;
    03915    ast_moh_stop_ptr = NULL;
    03916    ast_moh_cleanup_ptr = NULL;
    03917 }
    03918
    03919 /*! Turn on music on hold on a given channel */
    03920 int ast_moh_start(struct ast_channel *chan, char *mclass)
    03921 {
    03922    if (ast_moh_start_ptr)
    03923       return ast_moh_start_ptr(chan, mclass);
    03924
    03925    if (option_verbose > 2)
    03926       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : "default");
    03927
    03928    return 0;
    03929 }
    03930
    03931 /*! Turn off music on hold on a given channel */
    03932 void ast_moh_stop(struct ast_channel *chan)
    03933 {
    03934    if(ast_moh_stop_ptr)
    03935       ast_moh_stop_ptr(chan);
    03936 }
    03937
    03938 void ast_moh_cleanup(struct ast_channel *chan)
    03939 {
    03940    if(ast_moh_cleanup_ptr)
    03941         ast_moh_cleanup_ptr(chan);
    03942 }
    03943
    03944 void ast_channels_init(void)
    03945 {
    03946    ast_cli_register(&cli_show_channeltypes);
    03947 }
    03948
    03949 /*--- ast_print_group: Print call group and pickup group ---*/
    03950 char *ast_print_group(char *buf, int buflen, ast_group_t group)
    03951 {
    03952    unsigned int i;
    03953    int first=1;
    03954    char num[3];
    03955
    03956    buf[0] = '\0';
    03957
    03958    if (!group) /* Return empty string if no group */
    03959       return(buf);
    03960
    03961    for (i=0; i<=63; i++) { /* Max group is 63 */
    03962       if (group & ((ast_group_t) 1 << i)) {
    03963             if (!first) {
    03964             strncat(buf, ", ", buflen);
    03965          } else {
    03966             first=0;
    03967          }
    03968          snprintf(num, sizeof(num), "%u", i);
    03969          strncat(buf, num, buflen);
    03970       }
    03971    }
    03972    return(buf);
    03973 }
    03974
    03975 void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
    03976 {
    03977    struct ast_variable *cur;
    03978
    03979    for (cur = vars; cur; cur = cur->next)
    03980       pbx_builtin_setvar_helper(chan, cur->name, cur->value);
    03981 }
    03982
    03983 static void copy_data_from_queue(struct ast_channel_spy_queue *queue, short *buf, unsigned int samples)
    03984 {
    03985    struct ast_frame *f;
    03986    int tocopy;
    03987    int bytestocopy;
    03988
    03989    while (samples) {
    03990       f = queue->head;
    03991
    03992       if (!f) {
    03993          ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n");
    03994          break;
    03995       }
    03996
    03997       tocopy = (f->samples > samples) ? samples : f->samples;
    03998       bytestocopy = ast_codec_get_len(queue->format, tocopy);
    03999       memcpy(buf, f->data, bytestocopy);
    04000       samples -= tocopy;
    04001       buf += tocopy;
    04002       f->samples -= tocopy;
    04003       f->data += bytestocopy;
    04004       f->datalen -= bytestocopy;
    04005       f->offset += bytestocopy;
    04006       queue->samples -= tocopy;
    04007       if (!f->samples) {
    04008          queue->head = f->next;
    04009          ast_frfree(f);
    04010       }
    04011    }
    04012 }
    04013
    04014 struct ast_frame *ast_channel_spy_read_frame(struct ast_channel_spy *spy, unsigned int samples)
    04015 {
    04016    struct ast_frame *result;
    04017    /* buffers are allocated to hold SLINEAR, which is the largest format */
    04018         short read_buf[samples];
    04019         short write_buf[samples];
    04020    struct ast_frame *read_frame;
    04021    struct ast_frame *write_frame;
    04022    int need_dup;
    04023    struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE,
    04024                      .subclass = spy->read_queue.format,
    04025                      .data = read_buf,
    04026                      .samples = samples,
    04027                      .datalen = ast_codec_get_len(spy->read_queue.format, samples),
    04028    };
    04029    struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE,
    04030                       .subclass = spy->write_queue.format,
    04031                       .data = write_buf,
    04032                       .samples = samples,
    04033                       .datalen = ast_codec_get_len(spy->write_queue.format, samples),
    04034    };
    04035
    04036    /* if a flush has been requested, dump everything in whichever queue is larger */
    04037    if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) {
    04038       if (spy->read_queue.samples > spy->write_queue.samples) {
    04039          if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) {
    04040             for (result = spy->read_queue.head; result; result = result->next)
    04041                ast_frame_adjust_volume(result, spy->read_vol_adjustment);
    04042          }
    04043          result = spy->read_queue.head;
    04044          spy->read_queue.head = NULL;
    04045          spy->read_queue.samples = 0;
    04046          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
    04047          return result;
    04048       } else {
    04049          if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
    04050             for (result = spy->write_queue.head; result; result = result->next)
    04051                ast_frame_adjust_volume(result, spy->write_vol_adjustment);
    04052          }
    04053          result = spy->write_queue.head;
    04054          spy->write_queue.head = NULL;
    04055          spy->write_queue.samples = 0;
    04056          ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
    04057          return result;
    04058       }
    04059    }
    04060
    04061    if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))
    04062       return NULL;
    04063
    04064    /* short-circuit if both head frames have exactly what we want */
    04065    if ((spy->read_queue.head->samples == samples) &&
    04066        (spy->write_queue.head->samples == samples)) {
    04067       read_frame = spy->read_queue.head;
    04068       spy->read_queue.head = read_frame->next;
    04069       read_frame->next = NULL;
    04070
    04071       write_frame = spy->write_queue.head;
    04072       spy->write_queue.head = write_frame->next;
    04073       write_frame->next = NULL;
    04074
    04075       spy->read_queue.samples -= samples;
    04076       spy->write_queue.samples -= samples;
    04077
    04078       need_dup = 0;
    04079    } else {
    04080       copy_data_from_queue(&spy->read_queue, read_buf, samples);
    04081       copy_data_from_queue(&spy->write_queue, write_buf, samples);
    04082
    04083       read_frame = &stack_read_frame;
    04084       write_frame = &stack_write_frame;
    04085       need_dup = 1;
    04086    }
    04087
    04088    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST))
    04089       ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment);
    04090
    04091    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST))
    04092       ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment);
    04093
    04094    if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) {
    04095       ast_frame_slinear_sum(read_frame, write_frame);
    04096
    04097       if (need_dup)
    04098          result = ast_frdup(read_frame);
    04099       else {
    04100          result = read_frame;
    04101          ast_frfree(write_frame);
    04102       }
    04103    } else {
    04104       if (need_dup) {
    04105          result = ast_frdup(read_frame);
    04106          result->next = ast_frdup(write_frame);
    04107       } else {
    04108          result = read_frame;
    04109          result->next = write_frame;
    04110       }
    04111    }
    04112
    04113    return result;
    04114 }
    04115
    04116 static void *silence_generator_alloc(struct ast_channel *chan, void *data)
    04117 {
    04118    /* just store the data pointer in the channel structure */
    04119    return data;
    04120 }
    04121
    04122 static void silence_generator_release(struct ast_channel *chan, void *data)
    04123 {
    04124    /* nothing to do */
    04125 }
    04126
    04127 static int silence_generator_generate(struct ast_channel *chan, void *data, int len, int samples)
    04128 {
    04129    if (samples == 160) {
    04130       short buf[160] = { 0, };
    04131       struct ast_frame frame = {
    04132          .frametype = AST_FRAME_VOICE,
    04133          .subclass = AST_FORMAT_SLINEAR,
    04134          .data = buf,
    04135          .samples = 160,
    04136          .datalen = sizeof(buf),
    04137       };
    04138
    04139       if (ast_write(chan, &frame))
    04140          return -1;
    04141    } else {
    04142       short buf[samples];
    04143       int x;
    04144       struct ast_frame frame = {
    04145          .frametype = AST_FRAME_VOICE,
    04146          .subclass = AST_FORMAT_SLINEAR,
    04147          .data = buf,
    04148          .samples = samples,
    04149          .datalen = sizeof(buf),
    04150       };
    04151
    04152       for (x = 0; x < samples; x++)
    04153          buf[x] = 0;
    04154
    04155       if (ast_write(chan, &frame))
    04156          return -1;
    04157    }
    04158
    04159    return 0;
    04160 }
    04161
    04162 static struct ast_generator silence_generator = {
    04163    .alloc = silence_generator_alloc,
    04164    .release = silence_generator_release,
    04165    .generate = silence_generator_generate,
    04166 };
    04167
    04168 struct ast_silence_generator {
    04169    int old_write_format;
    04170 };
    04171
    04172 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
    04173 {
    04174    struct ast_silence_generator *state;
    04175
    04176    if (!(state = calloc(1, sizeof(*state)))) {
    04177       ast_log(LOG_WARNING, "Could not allocate state structure\n");
    04178       return NULL;
    04179    }
    04180
    04181    state->old_write_format = chan->writeformat;
    04182
    04183    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
    04184       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
    04185       free(state);
    04186       return NULL;
    04187    }
    04188
    04189    ast_activate_generator(chan, &silence_generator, state);
    04190
    04191    if (option_debug)
    04192       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
    04193
    04194    return state;
    04195 }
    04196
    04197 void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
    04198 {
    04199    if (!state)
    04200       return;
    04201
    04202    ast_deactivate_generator(chan);
    04203
    04204    if (option_debug)
    04205       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
    04206
    04207    if (ast_set_write_format(chan, state->old_write_format) < 0)
    04208       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
    04209
    04210    free(state);
    04211 }