Sat Nov 1 06:28:30 2008

Asterisk developer's documentation


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  * \author Mark Spencer <markster@digium.com>
00024  */
00025 
00026 #include "asterisk.h"
00027 
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 150557 $")
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <stdarg.h>
00033 #include <string.h>
00034 #include <sys/time.h>
00035 #include <signal.h>
00036 #include <errno.h>
00037 #include <unistd.h>
00038 #include <math.h>
00039 
00040 #if defined(HAVE_DAHDI)
00041 #include <sys/ioctl.h>
00042 #include "asterisk/dahdi_compat.h"
00043 #endif
00044 
00045 #include "asterisk/pbx.h"
00046 #include "asterisk/frame.h"
00047 #include "asterisk/sched.h"
00048 #include "asterisk/options.h"
00049 #include "asterisk/channel.h"
00050 #include "asterisk/audiohook.h"
00051 #include "asterisk/musiconhold.h"
00052 #include "asterisk/logger.h"
00053 #include "asterisk/say.h"
00054 #include "asterisk/file.h"
00055 #include "asterisk/cli.h"
00056 #include "asterisk/translate.h"
00057 #include "asterisk/manager.h"
00058 #include "asterisk/chanvars.h"
00059 #include "asterisk/linkedlists.h"
00060 #include "asterisk/indications.h"
00061 #include "asterisk/monitor.h"
00062 #include "asterisk/causes.h"
00063 #include "asterisk/callerid.h"
00064 #include "asterisk/utils.h"
00065 #include "asterisk/lock.h"
00066 #include "asterisk/app.h"
00067 #include "asterisk/transcap.h"
00068 #include "asterisk/devicestate.h"
00069 #include "asterisk/sha1.h"
00070 #include "asterisk/threadstorage.h"
00071 #include "asterisk/slinfactory.h"
00072 
00073 /* uncomment if you have problems with 'monitoring' synchronized files */
00074 #if 0
00075 #define MONITOR_CONSTANT_DELAY
00076 #define MONITOR_DELAY   150 * 8     /* 150 ms of MONITORING DELAY */
00077 #endif
00078 
00079 /*! Prevent new channel allocation if shutting down. */
00080 static int shutting_down;
00081 
00082 static int uniqueint;
00083 
00084 unsigned long global_fin, global_fout;
00085 
00086 AST_THREADSTORAGE(state2str_threadbuf, state2str_threadbuf_init);
00087 #define STATE2STR_BUFSIZE   32
00088 
00089 /*! Default amount of time to use when emulating a digit as a begin and end 
00090  *  100ms */
00091 #define AST_DEFAULT_EMULATE_DTMF_DURATION 100
00092 
00093 /*! Minimum allowed digit length - 80ms */
00094 #define AST_MIN_DTMF_DURATION 80
00095 
00096 /*! Minimum amount of time between the end of the last digit and the beginning 
00097  *  of a new one - 45ms */
00098 #define AST_MIN_DTMF_GAP 45
00099 
00100 struct chanlist {
00101    const struct ast_channel_tech *tech;
00102    AST_LIST_ENTRY(chanlist) list;
00103 };
00104 
00105 /*! the list of registered channel types */
00106 static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist);
00107 
00108 /*! the list of channels we have. Note that the lock for this list is used for
00109     both the channels list and the backends list.  */
00110 static AST_LIST_HEAD_STATIC(channels, ast_channel);
00111 
00112 /*! map AST_CAUSE's to readable string representations */
00113 const struct ast_cause {
00114    int cause;
00115    const char *name;
00116    const char *desc;
00117 } causes[] = {
00118    { AST_CAUSE_UNALLOCATED, "UNALLOCATED", "Unallocated (unassigned) number" },
00119    { AST_CAUSE_NO_ROUTE_TRANSIT_NET, "NO_ROUTE_TRANSIT_NET", "No route to specified transmit network" },
00120    { AST_CAUSE_NO_ROUTE_DESTINATION, "NO_ROUTE_DESTINATION", "No route to destination" },
00121    { AST_CAUSE_CHANNEL_UNACCEPTABLE, "CHANNEL_UNACCEPTABLE", "Channel unacceptable" },
00122    { AST_CAUSE_CALL_AWARDED_DELIVERED, "CALL_AWARDED_DELIVERED", "Call awarded and being delivered in an established channel" },
00123    { AST_CAUSE_NORMAL_CLEARING, "NORMAL_CLEARING", "Normal Clearing" },
00124    { AST_CAUSE_USER_BUSY, "USER_BUSY", "User busy" },
00125    { AST_CAUSE_NO_USER_RESPONSE, "NO_USER_RESPONSE", "No user responding" },
00126    { AST_CAUSE_NO_ANSWER, "NO_ANSWER", "User alerting, no answer" },
00127    { AST_CAUSE_CALL_REJECTED, "CALL_REJECTED", "Call Rejected" },
00128    { AST_CAUSE_NUMBER_CHANGED, "NUMBER_CHANGED", "Number changed" },
00129    { AST_CAUSE_DESTINATION_OUT_OF_ORDER, "DESTINATION_OUT_OF_ORDER", "Destination out of order" },
00130    { AST_CAUSE_INVALID_NUMBER_FORMAT, "INVALID_NUMBER_FORMAT", "Invalid number format" },
00131    { AST_CAUSE_FACILITY_REJECTED, "FACILITY_REJECTED", "Facility rejected" },
00132    { AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY, "RESPONSE_TO_STATUS_ENQUIRY", "Response to STATus ENQuiry" },
00133    { AST_CAUSE_NORMAL_UNSPECIFIED, "NORMAL_UNSPECIFIED", "Normal, unspecified" },
00134    { AST_CAUSE_NORMAL_CIRCUIT_CONGESTION, "NORMAL_CIRCUIT_CONGESTION", "Circuit/channel congestion" },
00135    { AST_CAUSE_NETWORK_OUT_OF_ORDER, "NETWORK_OUT_OF_ORDER", "Network out of order" },
00136    { AST_CAUSE_NORMAL_TEMPORARY_FAILURE, "NORMAL_TEMPORARY_FAILURE", "Temporary failure" },
00137    { AST_CAUSE_SWITCH_CONGESTION, "SWITCH_CONGESTION", "Switching equipment congestion" },
00138    { AST_CAUSE_ACCESS_INFO_DISCARDED, "ACCESS_INFO_DISCARDED", "Access information discarded" },
00139    { AST_CAUSE_REQUESTED_CHAN_UNAVAIL, "REQUESTED_CHAN_UNAVAIL", "Requested channel not available" },
00140    { AST_CAUSE_PRE_EMPTED, "PRE_EMPTED", "Pre-empted" },
00141    { AST_CAUSE_FACILITY_NOT_SUBSCRIBED, "FACILITY_NOT_SUBSCRIBED", "Facility not subscribed" },
00142    { AST_CAUSE_OUTGOING_CALL_BARRED, "OUTGOING_CALL_BARRED", "Outgoing call barred" },
00143    { AST_CAUSE_INCOMING_CALL_BARRED, "INCOMING_CALL_BARRED", "Incoming call barred" },
00144    { AST_CAUSE_BEARERCAPABILITY_NOTAUTH, "BEARERCAPABILITY_NOTAUTH", "Bearer capability not authorized" },
00145    { AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, "BEARERCAPABILITY_NOTAVAIL", "Bearer capability not available" },
00146    { AST_CAUSE_BEARERCAPABILITY_NOTIMPL, "BEARERCAPABILITY_NOTIMPL", "Bearer capability not implemented" },
00147    { AST_CAUSE_CHAN_NOT_IMPLEMENTED, "CHAN_NOT_IMPLEMENTED", "Channel not implemented" },
00148    { AST_CAUSE_FACILITY_NOT_IMPLEMENTED, "FACILITY_NOT_IMPLEMENTED", "Facility not implemented" },
00149    { AST_CAUSE_INVALID_CALL_REFERENCE, "INVALID_CALL_REFERENCE", "Invalid call reference value" },
00150    { AST_CAUSE_INCOMPATIBLE_DESTINATION, "INCOMPATIBLE_DESTINATION", "Incompatible destination" },
00151    { AST_CAUSE_INVALID_MSG_UNSPECIFIED, "INVALID_MSG_UNSPECIFIED", "Invalid message unspecified" },
00152    { AST_CAUSE_MANDATORY_IE_MISSING, "MANDATORY_IE_MISSING", "Mandatory information element is missing" },
00153    { AST_CAUSE_MESSAGE_TYPE_NONEXIST, "MESSAGE_TYPE_NONEXIST", "Message type nonexist." },
00154    { AST_CAUSE_WRONG_MESSAGE, "WRONG_MESSAGE", "Wrong message" },
00155    { AST_CAUSE_IE_NONEXIST, "IE_NONEXIST", "Info. element nonexist or not implemented" },
00156    { AST_CAUSE_INVALID_IE_CONTENTS, "INVALID_IE_CONTENTS", "Invalid information element contents" },
00157    { AST_CAUSE_WRONG_CALL_STATE, "WRONG_CALL_STATE", "Message not compatible with call state" },
00158    { AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, "RECOVERY_ON_TIMER_EXPIRE", "Recover on timer expiry" },
00159    { AST_CAUSE_MANDATORY_IE_LENGTH_ERROR, "MANDATORY_IE_LENGTH_ERROR", "Mandatory IE length error" },
00160    { AST_CAUSE_PROTOCOL_ERROR, "PROTOCOL_ERROR", "Protocol error, unspecified" },
00161    { AST_CAUSE_INTERWORKING, "INTERWORKING", "Interworking, unspecified" },
00162 };
00163 
00164 struct ast_variable *ast_channeltype_list(void)
00165 {
00166    struct chanlist *cl;
00167    struct ast_variable *var=NULL, *prev = NULL;
00168    AST_LIST_TRAVERSE(&backends, cl, list) {
00169       if (prev)  {
00170          if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description)))
00171             prev = prev->next;
00172       } else {
00173          var = ast_variable_new(cl->tech->type, cl->tech->description);
00174          prev = var;
00175       }
00176    }
00177    return var;
00178 }
00179 
00180 static int show_channeltypes(int fd, int argc, char *argv[])
00181 {
00182 #define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n"
00183    struct chanlist *cl;
00184    int count_chan = 0;
00185 
00186    ast_cli(fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
00187    ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00188    if (AST_LIST_LOCK(&channels)) {
00189       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00190       return -1;
00191    }
00192    AST_LIST_TRAVERSE(&backends, cl, list) {
00193       ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
00194          (cl->tech->devicestate) ? "yes" : "no",
00195          (cl->tech->indicate) ? "yes" : "no",
00196          (cl->tech->transfer) ? "yes" : "no");
00197       count_chan++;
00198    }
00199    AST_LIST_UNLOCK(&channels);
00200    ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
00201    return RESULT_SUCCESS;
00202 
00203 #undef FORMAT
00204 
00205 }
00206 
00207 static int show_channeltype_deprecated(int fd, int argc, char *argv[])
00208 {
00209    struct chanlist *cl = NULL;
00210 
00211    if (argc != 3)
00212       return RESULT_SHOWUSAGE;
00213    
00214    if (AST_LIST_LOCK(&channels)) {
00215       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00216       return RESULT_FAILURE;
00217    }
00218 
00219    AST_LIST_TRAVERSE(&backends, cl, list) {
00220       if (!strncasecmp(cl->tech->type, argv[2], strlen(cl->tech->type))) {
00221          break;
00222       }
00223    }
00224 
00225 
00226    if (!cl) {
00227       ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[2]);
00228       AST_LIST_UNLOCK(&channels);
00229       return RESULT_FAILURE;
00230    }
00231 
00232    ast_cli(fd,
00233       "-- Info about channel driver: %s --\n"
00234       "  Device State: %s\n"
00235       "    Indication: %s\n"
00236       "     Transfer : %s\n"
00237       "  Capabilities: %d\n"
00238       "   Digit Begin: %s\n"
00239       "     Digit End: %s\n"
00240       "    Send HTML : %s\n"
00241       " Image Support: %s\n"
00242       "  Text Support: %s\n",
00243       cl->tech->type,
00244       (cl->tech->devicestate) ? "yes" : "no",
00245       (cl->tech->indicate) ? "yes" : "no",
00246       (cl->tech->transfer) ? "yes" : "no",
00247       (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00248       (cl->tech->send_digit_begin) ? "yes" : "no",
00249       (cl->tech->send_digit_end) ? "yes" : "no",
00250       (cl->tech->send_html) ? "yes" : "no",
00251       (cl->tech->send_image) ? "yes" : "no",
00252       (cl->tech->send_text) ? "yes" : "no"
00253       
00254    );
00255 
00256    AST_LIST_UNLOCK(&channels);
00257    return RESULT_SUCCESS;
00258 }
00259 
00260 static int show_channeltype(int fd, int argc, char *argv[])
00261 {
00262    struct chanlist *cl = NULL;
00263 
00264    if (argc != 4)
00265       return RESULT_SHOWUSAGE;
00266    
00267    if (AST_LIST_LOCK(&channels)) {
00268       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00269       return RESULT_FAILURE;
00270    }
00271 
00272    AST_LIST_TRAVERSE(&backends, cl, list) {
00273       if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) {
00274          break;
00275       }
00276    }
00277 
00278 
00279    if (!cl) {
00280       ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
00281       AST_LIST_UNLOCK(&channels);
00282       return RESULT_FAILURE;
00283    }
00284 
00285    ast_cli(fd,
00286       "-- Info about channel driver: %s --\n"
00287       "  Device State: %s\n"
00288       "    Indication: %s\n"
00289       "     Transfer : %s\n"
00290       "  Capabilities: %d\n"
00291       "   Digit Begin: %s\n"
00292       "     Digit End: %s\n"
00293       "    Send HTML : %s\n"
00294       " Image Support: %s\n"
00295       "  Text Support: %s\n",
00296       cl->tech->type,
00297       (cl->tech->devicestate) ? "yes" : "no",
00298       (cl->tech->indicate) ? "yes" : "no",
00299       (cl->tech->transfer) ? "yes" : "no",
00300       (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00301       (cl->tech->send_digit_begin) ? "yes" : "no",
00302       (cl->tech->send_digit_end) ? "yes" : "no",
00303       (cl->tech->send_html) ? "yes" : "no",
00304       (cl->tech->send_image) ? "yes" : "no",
00305       (cl->tech->send_text) ? "yes" : "no"
00306       
00307    );
00308 
00309    AST_LIST_UNLOCK(&channels);
00310    return RESULT_SUCCESS;
00311 }
00312 
00313 static char *complete_channeltypes_deprecated(const char *line, const char *word, int pos, int state)
00314 {
00315    struct chanlist *cl;
00316    int which = 0;
00317    int wordlen;
00318    char *ret = NULL;
00319 
00320    if (pos != 2)
00321       return NULL;
00322 
00323    wordlen = strlen(word);
00324 
00325    AST_LIST_TRAVERSE(&backends, cl, list) {
00326       if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
00327          ret = strdup(cl->tech->type);
00328          break;
00329       }
00330    }
00331    
00332    return ret;
00333 }
00334 
00335 static char *complete_channeltypes(const char *line, const char *word, int pos, int state)
00336 {
00337    struct chanlist *cl;
00338    int which = 0;
00339    int wordlen;
00340    char *ret = NULL;
00341 
00342    if (pos != 3)
00343       return NULL;
00344 
00345    wordlen = strlen(word);
00346 
00347    AST_LIST_TRAVERSE(&backends, cl, list) {
00348       if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
00349          ret = strdup(cl->tech->type);
00350          break;
00351       }
00352    }
00353    
00354    return ret;
00355 }
00356 
00357 static char show_channeltypes_usage[] =
00358 "Usage: core show channeltypes\n"
00359 "       Lists available channel types registered in your Asterisk server.\n";
00360 
00361 static char show_channeltype_usage[] =
00362 "Usage: core show channeltype <name>\n"
00363 "  Show details about the specified channel type, <name>.\n";
00364 
00365 static struct ast_cli_entry cli_show_channeltypes_deprecated = {
00366    { "show", "channeltypes", NULL },
00367    show_channeltypes, NULL,
00368    NULL };
00369 
00370 static struct ast_cli_entry cli_show_channeltype_deprecated = {
00371    { "show", "channeltype", NULL },
00372    show_channeltype_deprecated, NULL,
00373    NULL, complete_channeltypes_deprecated };
00374 
00375 static struct ast_cli_entry cli_channel[] = {
00376    { { "core", "show", "channeltypes", NULL },
00377    show_channeltypes, "List available channel types",
00378    show_channeltypes_usage, NULL, &cli_show_channeltypes_deprecated },
00379 
00380    { { "core", "show", "channeltype", NULL },
00381    show_channeltype, "Give more details on that channel type",
00382    show_channeltype_usage, complete_channeltypes, &cli_show_channeltype_deprecated },
00383 };
00384 
00385 /*! \brief Checks to see if a channel is needing hang up */
00386 int ast_check_hangup(struct ast_channel *chan)
00387 {
00388    if (chan->_softhangup)     /* yes if soft hangup flag set */
00389       return 1;
00390    if (!chan->tech_pvt)    /* yes if no technology private data */
00391       return 1;
00392    if (!chan->whentohangup)   /* no if no hangup scheduled */
00393       return 0;
00394    if (chan->whentohangup > time(NULL))   /* no if hangup time has not come yet. */
00395       return 0;
00396    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00397    return 1;
00398 }
00399 
00400 static int ast_check_hangup_locked(struct ast_channel *chan)
00401 {
00402    int res;
00403    ast_channel_lock(chan);
00404    res = ast_check_hangup(chan);
00405    ast_channel_unlock(chan);
00406    return res;
00407 }
00408 
00409 /*! \brief printf the string into a correctly sized mallocd buffer, and return the buffer */
00410 char *ast_safe_string_alloc(const char *fmt, ...)
00411 {
00412    char *b2, buf[1];
00413    int len;
00414    va_list args;
00415 
00416    va_start(args, fmt);
00417    len = vsnprintf(buf, 1, fmt, args);
00418    va_end(args);
00419 
00420    if (!(b2 = ast_malloc(len + 1)))
00421       return NULL;
00422 
00423    va_start(args, fmt);
00424    vsnprintf(b2, len + 1,  fmt, args);
00425    va_end(args);
00426 
00427    return b2;
00428 }
00429 
00430 /*! \brief Initiate system shutdown */
00431 void ast_begin_shutdown(int hangup)
00432 {
00433    struct ast_channel *c;
00434    shutting_down = 1;
00435    if (hangup) {
00436       AST_LIST_LOCK(&channels);
00437       AST_LIST_TRAVERSE(&channels, c, chan_list)
00438          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00439       AST_LIST_UNLOCK(&channels);
00440    }
00441 }
00442 
00443 /*! \brief returns number of active/allocated channels */
00444 int ast_active_channels(void)
00445 {
00446    struct ast_channel *c;
00447    int cnt = 0;
00448    AST_LIST_LOCK(&channels);
00449    AST_LIST_TRAVERSE(&channels, c, chan_list)
00450       cnt++;
00451    AST_LIST_UNLOCK(&channels);
00452    return cnt;
00453 }
00454 
00455 /*! \brief Cancel a shutdown in progress */
00456 void ast_cancel_shutdown(void)
00457 {
00458    shutting_down = 0;
00459 }
00460 
00461 /*! \brief Returns non-zero if Asterisk is being shut down */
00462 int ast_shutting_down(void)
00463 {
00464    return shutting_down;
00465 }
00466 
00467 /*! \brief Set when to hangup channel */
00468 void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
00469 {
00470    chan->whentohangup = offset ? time(NULL) + offset : 0;
00471    ast_queue_frame(chan, &ast_null_frame);
00472    return;
00473 }
00474 
00475 /*! \brief Compare a offset with when to hangup channel */
00476 int ast_channel_cmpwhentohangup(struct ast_channel *chan, time_t offset)
00477 {
00478    time_t whentohangup;
00479 
00480    if (chan->whentohangup == 0) {
00481       return (offset == 0) ? 0 : -1;
00482    } else {
00483       if (offset == 0)  /* XXX why is this special ? */
00484          return (1);
00485       else {
00486          whentohangup = offset + time (NULL);
00487          if (chan->whentohangup < whentohangup)
00488             return (1);
00489          else if (chan->whentohangup == whentohangup)
00490             return (0);
00491          else
00492             return (-1);
00493       }
00494    }
00495 }
00496 
00497 /*! \brief Register a new telephony channel in Asterisk */
00498 int ast_channel_register(const struct ast_channel_tech *tech)
00499 {
00500    struct chanlist *chan;
00501 
00502    AST_LIST_LOCK(&channels);
00503 
00504    AST_LIST_TRAVERSE(&backends, chan, list) {
00505       if (!strcasecmp(tech->type, chan->tech->type)) {
00506          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00507          AST_LIST_UNLOCK(&channels);
00508          return -1;
00509       }
00510    }
00511    
00512    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00513       AST_LIST_UNLOCK(&channels);
00514       return -1;
00515    }
00516    chan->tech = tech;
00517    AST_LIST_INSERT_HEAD(&backends, chan, list);
00518 
00519    if (option_debug)
00520       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00521 
00522    if (option_verbose > 1)
00523       ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00524              chan->tech->description);
00525 
00526    AST_LIST_UNLOCK(&channels);
00527    return 0;
00528 }
00529 
00530 void ast_channel_unregister(const struct ast_channel_tech *tech)
00531 {
00532    struct chanlist *chan;
00533 
00534    if (option_debug)
00535       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00536 
00537    AST_LIST_LOCK(&channels);
00538 
00539    AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00540       if (chan->tech == tech) {
00541          AST_LIST_REMOVE_CURRENT(&backends, list);
00542          free(chan);
00543          if (option_verbose > 1)
00544             ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00545          break;   
00546       }
00547    }
00548    AST_LIST_TRAVERSE_SAFE_END
00549 
00550    AST_LIST_UNLOCK(&channels);
00551 }
00552 
00553 const struct ast_channel_tech *ast_get_channel_tech(const char *name)
00554 {
00555    struct chanlist *chanls;
00556    const struct ast_channel_tech *ret = NULL;
00557 
00558    if (AST_LIST_LOCK(&channels)) {
00559       ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00560       return NULL;
00561    }
00562 
00563    AST_LIST_TRAVERSE(&backends, chanls, list) {
00564       if (!strcasecmp(name, chanls->tech->type)) {
00565          ret = chanls->tech;
00566          break;
00567       }
00568    }
00569 
00570    AST_LIST_UNLOCK(&channels);
00571    
00572    return ret;
00573 }
00574 
00575 /*! \brief Gives the string form of a given hangup cause */
00576 const char *ast_cause2str(int cause)
00577 {
00578    int x;
00579 
00580    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) {
00581       if (causes[x].cause == cause)
00582          return causes[x].desc;
00583    }
00584 
00585    return "Unknown";
00586 }
00587 
00588 /*! \brief Convert a symbolic hangup cause to number */
00589 int ast_str2cause(const char *name)
00590 {
00591    int x;
00592 
00593    for (x = 0; x < sizeof(causes) / sizeof(causes[0]); x++)
00594       if (strncasecmp(causes[x].name, name, strlen(causes[x].name)) == 0)
00595          return causes[x].cause;
00596 
00597    return -1;
00598 }
00599 
00600 /*! \brief Gives the string form of a given channel state */
00601 char *ast_state2str(enum ast_channel_state state)
00602 {
00603    char *buf;
00604 
00605    switch(state) {
00606    case AST_STATE_DOWN:
00607       return "Down";
00608    case AST_STATE_RESERVED:
00609       return "Rsrvd";
00610    case AST_STATE_OFFHOOK:
00611       return "OffHook";
00612    case AST_STATE_DIALING:
00613       return "Dialing";
00614    case AST_STATE_RING:
00615       return "Ring";
00616    case AST_STATE_RINGING:
00617       return "Ringing";
00618    case AST_STATE_UP:
00619       return "Up";
00620    case AST_STATE_BUSY:
00621       return "Busy";
00622    case AST_STATE_DIALING_OFFHOOK:
00623       return "Dialing Offhook";
00624    case AST_STATE_PRERING:
00625       return "Pre-ring";
00626    default:
00627       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00628          return "Unknown";
00629       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00630       return buf;
00631    }
00632 }
00633 
00634 /*! \brief Gives the string form of a given transfer capability */
00635 char *ast_transfercapability2str(int transfercapability)
00636 {
00637    switch(transfercapability) {
00638    case AST_TRANS_CAP_SPEECH:
00639       return "SPEECH";
00640    case AST_TRANS_CAP_DIGITAL:
00641       return "DIGITAL";
00642    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00643       return "RESTRICTED_DIGITAL";
00644    case AST_TRANS_CAP_3_1K_AUDIO:
00645       return "3K1AUDIO";
00646    case AST_TRANS_CAP_DIGITAL_W_TONES:
00647       return "DIGITAL_W_TONES";
00648    case AST_TRANS_CAP_VIDEO:
00649       return "VIDEO";
00650    default:
00651       return "UNKNOWN";
00652    }
00653 }
00654 
00655 /*! \brief Pick the best audio codec */
00656 int ast_best_codec(int fmts)
00657 {
00658    /* This just our opinion, expressed in code.  We are asked to choose
00659       the best codec to use, given no information */
00660    int x;
00661    static int prefs[] =
00662    {
00663       /*! Okay, ulaw is used by all telephony equipment, so start with it */
00664       AST_FORMAT_ULAW,
00665       /*! Unless of course, you're a silly European, so then prefer ALAW */
00666       AST_FORMAT_ALAW,
00667       /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
00668       AST_FORMAT_G722,
00669       /*! Okay, well, signed linear is easy to translate into other stuff */
00670       AST_FORMAT_SLINEAR,
00671       /*! G.726 is standard ADPCM, in RFC3551 packing order */
00672       AST_FORMAT_G726,
00673       /*! G.726 is standard ADPCM, in AAL2 packing order */
00674       AST_FORMAT_G726_AAL2,
00675       /*! ADPCM has great sound quality and is still pretty easy to translate */
00676       AST_FORMAT_ADPCM,
00677       /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00678           translate and sounds pretty good */
00679       AST_FORMAT_GSM,
00680       /*! iLBC is not too bad */
00681       AST_FORMAT_ILBC,
00682       /*! Speex is free, but computationally more expensive than GSM */
00683       AST_FORMAT_SPEEX,
00684       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00685           to use it */
00686       AST_FORMAT_LPC10,
00687       /*! G.729a is faster than 723 and slightly less expensive */
00688       AST_FORMAT_G729A,
00689       /*! Down to G.723.1 which is proprietary but at least designed for voice */
00690       AST_FORMAT_G723_1,
00691    };
00692 
00693    /* Strip out video */
00694    fmts &= AST_FORMAT_AUDIO_MASK;
00695    
00696    /* Find the first preferred codec in the format given */
00697    for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00698       if (fmts & prefs[x])
00699          return prefs[x];
00700    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00701    return 0;
00702 }
00703 
00704 static const struct ast_channel_tech null_tech = {
00705    .type = "NULL",
00706    .description = "Null channel (should not see this)",
00707 };
00708 
00709 /*! \brief Create a new channel structure */
00710 struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...)
00711 {
00712    struct ast_channel *tmp;
00713    int x;
00714    int flags;
00715    struct varshead *headp;
00716    va_list ap1, ap2;
00717 
00718    /* If shutting down, don't allocate any new channels */
00719    if (shutting_down) {
00720       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00721       return NULL;
00722    }
00723 
00724    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
00725       return NULL;
00726 
00727    if (!(tmp->sched = sched_context_create())) {
00728       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00729       free(tmp);
00730       return NULL;
00731    }
00732    
00733    if ((ast_string_field_init(tmp, 128))) {
00734       sched_context_destroy(tmp->sched);
00735       free(tmp);
00736       return NULL;
00737    }
00738 
00739    /* Don't bother initializing the last two FD here, because they
00740       will *always* be set just a few lines down (AST_TIMING_FD,
00741       AST_ALERT_FD). */
00742    for (x = 0; x < AST_MAX_FDS - 2; x++)
00743       tmp->fds[x] = -1;
00744 
00745 #ifdef HAVE_DAHDI
00746 
00747 #ifdef HAVE_ZAPTEL
00748    tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00749 #else
00750    tmp->timingfd = open("/dev/dahdi/timer", O_RDWR);
00751 #endif
00752 
00753    if (tmp->timingfd > -1) {
00754       /* Check if timing interface supports new
00755          ping/pong scheme */
00756       flags = 1;
00757       if (!ioctl(tmp->timingfd, DAHDI_TIMERPONG, &flags))
00758          needqueue = 0;
00759    }
00760 #else
00761    tmp->timingfd = -1;              
00762 #endif               
00763 
00764    if (needqueue) {
00765       if (pipe(tmp->alertpipe)) {
00766          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
00767 alertpipe_failed:
00768 #ifdef HAVE_DAHDI
00769          if (tmp->timingfd > -1)
00770             close(tmp->timingfd);
00771 #endif
00772          sched_context_destroy(tmp->sched);
00773          ast_string_field_free_memory(tmp);
00774          free(tmp);
00775          return NULL;
00776       } else {
00777          flags = fcntl(tmp->alertpipe[0], F_GETFL);
00778          if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
00779             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
00780             close(tmp->alertpipe[0]);
00781             close(tmp->alertpipe[1]);
00782             goto alertpipe_failed;
00783          }
00784          flags = fcntl(tmp->alertpipe[1], F_GETFL);
00785          if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
00786             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
00787             close(tmp->alertpipe[0]);
00788             close(tmp->alertpipe[1]);
00789             goto alertpipe_failed;
00790          }
00791       }
00792    } else   /* Make sure we've got it done right if they don't */
00793       tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00794 
00795    /* Always watch the alertpipe */
00796    tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0];
00797    /* And timing pipe */
00798    tmp->fds[AST_TIMING_FD] = tmp->timingfd;
00799    ast_string_field_set(tmp, name, "**Unknown**");
00800 
00801    /* Initial state */
00802    tmp->_state = state;
00803 
00804    tmp->streamid = -1;
00805    
00806    tmp->fin = global_fin;
00807    tmp->fout = global_fout;
00808 
00809    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00810       ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 
00811          ast_atomic_fetchadd_int(&uniqueint, 1));
00812    } else {
00813       ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 
00814          (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00815    }
00816 
00817    tmp->cid.cid_name = ast_strdup(cid_name);
00818    tmp->cid.cid_num = ast_strdup(cid_num);
00819    
00820    if (!ast_strlen_zero(name_fmt)) {
00821       /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
00822        * And they all use slightly different formats for their name string.
00823        * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
00824        * This means, that the stringfields must have a routine that takes the va_lists directly, and 
00825        * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
00826        * This new function was written so this can be accomplished.
00827        */
00828       va_start(ap1, name_fmt);
00829       va_start(ap2, name_fmt);
00830       ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
00831       va_end(ap1);
00832       va_end(ap2);
00833    }
00834 
00835    /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
00836 
00837    /* These 4 variables need to be set up for the cdr_init() to work right */
00838    if (amaflag)
00839       tmp->amaflags = amaflag;
00840    else
00841       tmp->amaflags = ast_default_amaflags;
00842    
00843    if (!ast_strlen_zero(acctcode))
00844       ast_string_field_set(tmp, accountcode, acctcode);
00845    else
00846       ast_string_field_set(tmp, accountcode, ast_default_accountcode);
00847       
00848    if (!ast_strlen_zero(context))
00849       ast_copy_string(tmp->context, context, sizeof(tmp->context));
00850    else
00851       strcpy(tmp->context, "default");
00852 
00853    if (!ast_strlen_zero(exten))
00854       ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
00855    else
00856       strcpy(tmp->exten, "s");
00857 
00858    tmp->priority = 1;
00859       
00860    tmp->cdr = ast_cdr_alloc();
00861    ast_cdr_init(tmp->cdr, tmp);
00862    ast_cdr_start(tmp->cdr);
00863    
00864    headp = &tmp->varshead;
00865    AST_LIST_HEAD_INIT_NOLOCK(headp);
00866    
00867    ast_mutex_init(&tmp->lock);
00868    
00869    AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
00870    
00871    ast_string_field_set(tmp, language, defaultlanguage);
00872 
00873    tmp->tech = &null_tech;
00874 
00875    AST_LIST_LOCK(&channels);
00876    AST_LIST_INSERT_HEAD(&channels, tmp, chan_list);
00877    AST_LIST_UNLOCK(&channels);
00878 
00879    /*\!note
00880     * and now, since the channel structure is built, and has its name, let's
00881     * call the manager event generator with this Newchannel event. This is the
00882     * proper and correct place to make this call, but you sure do have to pass
00883     * a lot of data into this func to do it here!
00884     */
00885    if (!ast_strlen_zero(name_fmt)) {
00886       manager_event(EVENT_FLAG_CALL, "Newchannel",
00887             "Channel: %s\r\n"
00888             "State: %s\r\n"
00889             "CallerIDNum: %s\r\n"
00890             "CallerIDName: %s\r\n"
00891             "Uniqueid: %s\r\n",
00892             tmp->name, ast_state2str(state),
00893             S_OR(cid_num, "<unknown>"),
00894             S_OR(cid_name, "<unknown>"),
00895             tmp->uniqueid);
00896    }
00897 
00898    return tmp;
00899 }
00900 
00901 /*! \brief Queue an outgoing media frame */
00902 int ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin)
00903 {
00904    struct ast_frame *f;
00905    struct ast_frame *cur;
00906    int blah = 1;
00907    int qlen = 0;
00908 
00909    /* Build us a copy and free the original one */
00910    if (!(f = ast_frdup(fin))) {
00911       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00912       return -1;
00913    }
00914    ast_channel_lock(chan);
00915 
00916    /* See if the last frame on the queue is a hangup, if so don't queue anything */
00917    if ((cur = AST_LIST_LAST(&chan->readq)) && (cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00918       ast_frfree(f);
00919       ast_channel_unlock(chan);
00920       return 0;
00921    }
00922 
00923    /* Count how many frames exist on the queue */
00924    AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
00925       qlen++;
00926    }
00927 
00928    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00929    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
00930       if (fin->frametype != AST_FRAME_VOICE) {
00931          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00932          ast_assert(fin->frametype == AST_FRAME_VOICE);
00933       } else {
00934          if (option_debug)
00935             ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00936          ast_frfree(f);
00937          ast_channel_unlock(chan);
00938          return 0;
00939       }
00940    }
00941    AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
00942    if (chan->alertpipe[1] > -1) {
00943       if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00944          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00945             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00946 #ifdef HAVE_DAHDI
00947    } else if (chan->timingfd > -1) {
00948       ioctl(chan->timingfd, DAHDI_TIMERPING, &blah);
00949 #endif            
00950    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
00951       pthread_kill(chan->blocker, SIGURG);
00952    }
00953    ast_channel_unlock(chan);
00954    return 0;
00955 }
00956 
00957 /*! \brief Queue a hangup frame for channel */
00958 int