00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00074 #if 0
00075 #define MONITOR_CONSTANT_DELAY
00076 #define MONITOR_DELAY 150 * 8
00077 #endif
00078
00079
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
00090
00091 #define AST_DEFAULT_EMULATE_DTMF_DURATION 100
00092
00093
00094 #define AST_MIN_DTMF_DURATION 80
00095
00096
00097
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
00106 static AST_LIST_HEAD_NOLOCK_STATIC(backends, chanlist);
00107
00108
00109
00110 static AST_LIST_HEAD_STATIC(channels, ast_channel);
00111
00112
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
00386 int ast_check_hangup(struct ast_channel *chan)
00387 {
00388 if (chan->_softhangup)
00389 return 1;
00390 if (!chan->tech_pvt)
00391 return 1;
00392 if (!chan->whentohangup)
00393 return 0;
00394 if (chan->whentohangup > time(NULL))
00395 return 0;
00396 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
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
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
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
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
00456 void ast_cancel_shutdown(void)
00457 {
00458 shutting_down = 0;
00459 }
00460
00461
00462 int ast_shutting_down(void)
00463 {
00464 return shutting_down;
00465 }
00466
00467
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
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)
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
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
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
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
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
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
00656 int ast_best_codec(int fmts)
00657 {
00658
00659
00660 int x;
00661 static int prefs[] =
00662 {
00663
00664 AST_FORMAT_ULAW,
00665
00666 AST_FORMAT_ALAW,
00667
00668 AST_FORMAT_G722,
00669
00670 AST_FORMAT_SLINEAR,
00671
00672 AST_FORMAT_G726,
00673
00674 AST_FORMAT_G726_AAL2,
00675
00676 AST_FORMAT_ADPCM,
00677
00678
00679 AST_FORMAT_GSM,
00680
00681 AST_FORMAT_ILBC,
00682
00683 AST_FORMAT_SPEEX,
00684
00685
00686 AST_FORMAT_LPC10,
00687
00688 AST_FORMAT_G729A,
00689
00690 AST_FORMAT_G723_1,
00691 };
00692
00693
00694 fmts &= AST_FORMAT_AUDIO_MASK;
00695
00696
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
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
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
00740
00741
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
00755
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
00793 tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00794
00795
00796 tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0];
00797
00798 tmp->fds[AST_TIMING_FD] = tmp->timingfd;
00799 ast_string_field_set(tmp, name, "**Unknown**");
00800
00801
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
00822
00823
00824
00825
00826
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
00836
00837
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
00880
00881
00882
00883
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
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
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
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
00924 AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
00925 qlen++;
00926 }
00927
00928
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
00958 int