Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:24 2007

Asterisk developer's documentation :: Codename Pineapple


channel.c File Reference


Detailed Description

Channel Management.

Author:
Mark Spencer <markster@digium.com>

Definition in file channel.c.

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include "asterisk/zapata.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/chanspy.h"
#include "asterisk/musiconhold.h"
#include "asterisk/logger.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/chanvars.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/monitor.h"
#include "asterisk/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/transcap.h"
#include "asterisk/devicestate.h"
#include "asterisk/sha1.h"
#include "asterisk/threadstorage.h"
#include "asterisk/slinfactory.h"

Include dependency graph for channel.c:

Go to the source code of this file.

Data Structures

struct  ast_cause
struct  ast_channel_spy_list
struct  ast_channel_whisper_buffer
struct  ast_silence_generator
struct  chanlist
struct  channel_spy_trans
struct  tonepair_def
struct  tonepair_state

Defines

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100
#define FORMAT   "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"
#define SPY_QUEUE_SAMPLE_LIMIT   4000
#define STATE2STR_BUFSIZE   32

Enumerations

enum  spy_direction { SPY_READ, SPY_WRITE }

Functions

int __ast_answer (struct ast_channel *chan, unsigned int delay)
static struct ast_frame__ast_read (struct ast_channel *chan, int dropaudio)
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)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
 returns number of active/allocated channels
int ast_answer (struct ast_channel *chan)
 Answer a channel.
void ast_begin_shutdown (int hangup)
 Initiate system shutdown.
int ast_best_codec (int fmts)
 Pick the best audio codec.
ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
void ast_cancel_shutdown (void)
 Cancel a shutdown in progress.
const char * ast_cause2str (int cause)
 Gives the string form of a given hangup cause.
void ast_change_name (struct ast_channel *chan, char *newname)
 Change channel name.
ast_channelast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *name_fmt,...)
 Create a channel structure.
enum ast_bridge_result ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
 Bridge two channels together.
int ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset)
 Compare a offset with the settings of when to hang a channel up.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, char *uid)
 Create a channel datastore structure.
ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel datastore structure.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 Set defer DTMF flag on channel.
int ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1)
 Bridge two channels together (early).
void ast_channel_free (struct ast_channel *chan)
 Free a channel structure.
void ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child)
 Inherits channel variable from parent to child channel.
int ast_channel_make_compatible (struct ast_channel *chan, struct ast_channel *peer)
 Makes two channel formats compatible.
static int ast_channel_make_compatible_helper (struct ast_channel *from, struct ast_channel *to)
 Set up translation from one channel to another.
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
 Weird function made for call transfers.
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
int ast_channel_setoption (struct ast_channel *chan, int option, void *data, int datalen, int block)
 Sets an option on a channel.
void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.
int ast_channel_spy_add (struct ast_channel *chan, struct ast_channel_spy *spy)
 Adds a spy to a channel, to begin receiving copies of the channel's audio frames.
void ast_channel_spy_free (struct ast_channel_spy *spy)
 Free a spy.
ast_frameast_channel_spy_read_frame (struct ast_channel_spy *spy, unsigned int samples)
 Read one (or more) frames of audio from a channel being spied upon.
void ast_channel_spy_remove (struct ast_channel *chan, struct ast_channel_spy *spy)
 Remove a spy from a channel.
void ast_channel_spy_stop_by_type (struct ast_channel *chan, const char *type)
 Find all spies of a particular type on a channel and stop them.
void ast_channel_spy_trigger_wait (struct ast_channel_spy *spy)
 Efficiently wait until audio is available for a spy, or an exception occurs.
ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
int ast_channel_supports_html (struct ast_channel *chan)
void ast_channel_undefer_dtmf (struct ast_channel *chan)
 Unset defer DTMF flag on channel.
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
ast_channelast_channel_walk_locked (const struct ast_channel *prev)
 Browse channels in use Browse the channels currently in use.
int ast_channel_whisper_feed (struct ast_channel *chan, struct ast_frame *f)
 Feed an audio frame into the whisper buffer on a channel.
int ast_channel_whisper_start (struct ast_channel *chan)
 Begin 'whispering' onto a channel.
void ast_channel_whisper_stop (struct ast_channel *chan)
 Stop 'whispering' onto a channel.
void ast_channels_init (void)
ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Check to see if a channel is needing hang up.
static int ast_check_hangup_locked (struct ast_channel *chan)
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *original)
 Start masquerading a channel XXX This is a seriously whacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.
static enum ast_bridge_result ast_generic_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc, struct timeval bridge_end)
ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
 Get channel by exten (and optionally context) and lock it.
ast_channelast_get_channel_by_name_locked (const char *name)
 Get channel by name (locks channel).
ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
 Get channel by name prefix (locks channel).
const struct ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (const char *s)
int ast_hangup (struct ast_channel *chan)
 Hang up a channel.
int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.
int ast_indicate_data (struct ast_channel *chan, int condition, const void *data, size_t datalen)
 Indicates condition of channel, with payload.
void ast_install_music_functions (int(*start_ptr)(struct ast_channel *, const char *, const char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *))
int ast_internal_timing_enabled (struct ast_channel *chan)
 Check if the channel can run in internal timing mode.
static AST_LIST_HEAD_NOLOCK_STATIC (backends, chanlist)
static AST_LIST_HEAD_STATIC (channels, ast_channel)
void ast_moh_cleanup (struct ast_channel *chan)
int ast_moh_start (struct ast_channel *chan, const char *mclass, const char *interpclass)
 Turn on music on hold on a given channel.
void ast_moh_stop (struct ast_channel *chan)
 Turn off music on hold on a given channel.
char * ast_print_group (char *buf, int buflen, ast_group_t group)
 print call- and pickup groups into buffer
int ast_prod (struct ast_channel *chan)
 Send empty audio to prime a channel driver.
int ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control)
 Queue a control frame with payload.
int ast_queue_control_data (struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame with payload.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin)
 Queue an outgoing frame.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame.
ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
ast_frameast_read_noaudio (struct ast_channel *chan)
 Reads a frame, returning AST_FRAME_NULL frame if audio.
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.
char * ast_recvtext (struct ast_channel *chan, int timeout)
 Receives a text string from a channel Read a string of text from a channel.
ast_channelast_request (const char *type, int format, void *data, int *cause)
 Requests a channel.
ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait for a specified amount of time, looking for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait for a specified amount of time, looking for hangups and a condition argument.
int ast_say_character_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_say_digit_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_say_digits (struct ast_channel *chan, int num, const char *ints, const char *lang)
int ast_say_digits_full (struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
int ast_say_enumeration (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
int ast_say_number (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
int ast_say_phonetic_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_senddigit (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_begin (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration)
 Send a DTMF digit to a channel.
int ast_sendtext (struct ast_channel *chan, const char *text)
 Sends text to a channel Write text to a display on a channel.
void ast_set_callerid (struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
int ast_set_read_format (struct ast_channel *chan, int fmt)
 Sets read format on channel chan Set read format for channel to whichever component of "format" is best.
void ast_set_variables (struct ast_channel *chan, struct ast_variable *vars)
 adds a list of channel variables to a channel
int ast_set_write_format (struct ast_channel *chan, int fmt)
 Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
int ast_setstate (struct ast_channel *chan, enum ast_channel_state state)
 Change the state of a channel.
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data)
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel lock).
const char * ast_state2str (enum ast_channel_state state)
 Gives the string form of a given channel state.
int ast_str2cause (const char *name)
 Convert a symbolic hangup cause to number.
 AST_THREADSTORAGE (state2str_threadbuf)
int ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
int ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
void ast_tonepair_stop (struct ast_channel *chan)
int ast_transfer (struct ast_channel *chan, char *dest)
 Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
char * ast_transfercapability2str (int transfercapability)
 Gives the string form of a given transfer capability.
void ast_uninstall_music_functions (void)
int ast_waitfor (struct ast_channel *c, int ms)
 Wait for input on a channel.
ast_channelast_waitfor_n (struct ast_channel **c, int n, int *ms)
 Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
 Waits for input on an fd This version works on fd's only. Be careful with it.
ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Waits for activity on a group of channels.
int ast_waitfordigit (struct ast_channel *c, int ms)
 Waits for a digit.
int ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int cmdfd)
 Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
ast_channelast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context)
 Get next channel by exten (and optionally context) and lock it.
ast_channelast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen)
 Get channel by name prefix (locks channel).
int ast_write (struct ast_channel *chan, struct ast_frame *fr)
 Write a frame to a channel This function writes the given frame to the indicated channel.
int ast_write_video (struct ast_channel *chan, struct ast_frame *fr)
 Write video frame to a channel This function writes the given frame to the indicated channel.
static void bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
static struct ast_channelchannel_find_locked (const struct ast_channel *prev, const char *name, const int namelen, const char *context, const char *exten)
 Helper function to find channels.
const char * channelreloadreason2txt (enum channelreloadreason reason)
 Convert enum channelreloadreason to text string for manager event.
static void clone_variables (struct ast_channel *original, struct ast_channel *clone)
 Clone channel variables from 'clone' channel into 'original' channel.
static char * complete_channeltypes (const char *line, const char *word, int pos, int state)
static void copy_data_from_queue (struct ast_channel_spy_queue *queue, short *buf, unsigned int samples)
static void detach_spies (struct ast_channel *chan)
static void free_cid (struct ast_callerid *cid)
static void free_translation (struct ast_channel *clone)
static int generator_force (void *data)
static void queue_frame_to_spies (struct ast_channel *chan, struct ast_frame *f, enum spy_direction dir)
static int set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction)
static int show_channeltype (int fd, int argc, char *argv[])
static int show_channeltypes (int fd, int argc, char *argv[])
static void * silence_generator_alloc (struct ast_channel *chan, void *data)
static int silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples)
static void silence_generator_release (struct ast_channel *chan, void *data)
static void spy_cleanup (struct ast_channel *chan)
static void spy_detach (struct ast_channel_spy *spy, struct ast_channel *chan)
static void * tonepair_alloc (struct ast_channel *chan, void *params)
static int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
static void tonepair_release (struct ast_channel *chan, void *params)

Variables

static void(* ast_moh_cleanup_ptr )(struct ast_channel *) = NULL
static int(* ast_moh_start_ptr )(struct ast_channel *, const char *, const char *) = NULL
static void(* ast_moh_stop_ptr )(struct ast_channel *) = NULL
const struct ast_cause causes []
static struct ast_cli_entry cli_channel []
unsigned long global_fin
unsigned long global_fout
static const struct ast_channel_tech null_tech
static const char show_channeltype_usage []
static const char show_channeltypes_usage []
static int shutting_down
static struct ast_generator silence_generator
static struct ast_generator tonepair
static int uniqueint


Define Documentation

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100
 

100ms

Definition at line 105 of file channel.c.

Referenced by __ast_read().

#define FORMAT   "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"
 

#define SPY_QUEUE_SAMPLE_LIMIT   4000
 

Definition at line 1400 of file channel.c.

Referenced by queue_frame_to_spies().

#define STATE2STR_BUFSIZE   32
 

Definition at line 102 of file channel.c.

Referenced by ast_state2str().


Enumeration Type Documentation

enum spy_direction
 

Enumerator:
SPY_READ 
SPY_WRITE 

Definition at line 1395 of file channel.c.

01395                    {
01396    SPY_READ,
01397    SPY_WRITE,
01398 };


Function Documentation

int __ast_answer struct ast_channel chan,
unsigned int  delay
 

Definition at line 1612 of file channel.c.

References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_safe_sleep(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, and ast_channel::tech.

Referenced by ast_answer(), and pbx_builtin_answer().

01613 {
01614    int res = 0;
01615 
01616    ast_channel_lock(chan);
01617 
01618    /* You can't answer an outbound call */
01619    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01620       ast_channel_unlock(chan);
01621       return 0;
01622    }
01623 
01624    /* Stop if we're a zombie or need a soft hangup */
01625    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01626       ast_channel_unlock(chan);
01627       return -1;
01628    }
01629 
01630    switch (chan->_state) {
01631    case AST_STATE_RINGING:
01632    case AST_STATE_RING:
01633       if (chan->tech->answer)
01634          res = chan->tech->answer(chan);
01635       ast_setstate(chan, AST_STATE_UP);
01636       ast_cdr_answer(chan->cdr);
01637       ast_channel_unlock(chan);
01638       if (delay)
01639          ast_safe_sleep(chan, delay);
01640       return res;
01641       break;
01642    case AST_STATE_UP:
01643       ast_cdr_answer(chan->cdr);
01644       break;
01645    default:
01646       break;
01647    }
01648 
01649    ast_channel_unlock(chan);
01650 
01651    return res;
01652 }

static struct ast_frame* __ast_read struct ast_channel chan,
int  dropaudio
[static]
 

Definition at line 1977 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, ast_cdr_answer(), ast_cdr_end(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), AST_DEFAULT_EMULATE_DTMF_DURATION, ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_DTMF, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_VOICE, ast_frfree(), AST_GENERATOR_FD, ast_getformatname(), ast_internal_timing_enabled(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, ast_log(), AST_MONITOR_RUNNING, ast_null_frame, ast_seekstream(), ast_set_flag, ast_setstate(), ast_settimeout(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, AST_TIMING_FD, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, ast_frame::data, DEBUGCHAN_FLAG, ast_channel::dtmf_begin_tv, ast_channel::dtmff, ast_channel::dtmfq, ast_channel::emulate_dtmf_digit, ast_channel::emulate_dtmf_duration, ast_channel_tech::exception, ast_channel::fdno, ast_channel::fds, ast_channel::fin, FRAMECOUNT_INC, ast_frame::frametype, func, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::insmpl, LOG_DEBUG, LOG_DTMF, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::nativeformats, option_debug, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readtrans, SEEK_FORCECUR, ast_channel::spies, SPY_READ, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by ast_read(), and ast_read_noaudio().

01978 {
01979    struct ast_frame *f = NULL;   /* the return value */
01980    int blah;
01981    int prestate;
01982 
01983    /* this function is very long so make sure there is only one return
01984     * point at the end (there is only one exception to this).
01985     */
01986    ast_channel_lock(chan);
01987    if (chan->masq) {
01988       if (ast_do_masquerade(chan))
01989          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01990       else
01991          f =  &ast_null_frame;
01992       goto done;
01993    }
01994 
01995    /* Stop if we're a zombie or need a soft hangup */
01996    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01997       if (chan->generator)
01998          ast_deactivate_generator(chan);
01999       goto done;
02000    }
02001    prestate = chan->_state;
02002 
02003    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) && 
02004        !ast_strlen_zero(chan->dtmfq)) {
02005       /* We have DTMF that has been deferred.  Return it now */
02006       chan->dtmff.subclass = chan->dtmfq[0];
02007       /* Drop first digit from the buffer */
02008       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
02009       f = &chan->dtmff;
02010       if (ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY))
02011          chan->dtmff.frametype = AST_FRAME_DTMF_END;
02012       else {
02013          chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
02014          ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02015          chan->emulate_dtmf_digit = f->subclass;
02016          chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02017          chan->dtmf_begin_tv = ast_tvnow();
02018       }
02019       goto done;
02020    }
02021    
02022    /* Read and ignore anything on the alertpipe, but read only
02023       one sizeof(blah) per frame that we send from it */
02024    if (chan->alertpipe[0] > -1)
02025       read(chan->alertpipe[0], &blah, sizeof(blah));
02026 
02027 #ifdef HAVE_ZAPTEL
02028    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02029       int res;
02030 
02031       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02032       blah = -1;
02033       /* IF we can't get event, assume it's an expired as-per the old interface */
02034       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
02035       if (res)
02036          blah = ZT_EVENT_TIMER_EXPIRED;
02037 
02038       if (blah == ZT_EVENT_TIMER_PING) {
02039          if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
02040             /* Acknowledge PONG unless we need it again */
02041             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
02042                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
02043             }
02044          }
02045       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
02046          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
02047          if (chan->timingfunc) {
02048             /* save a copy of func/data before unlocking the channel */
02049             int (*func)(void *) = chan->timingfunc;
02050             void *data = chan->timingdata;
02051             ast_channel_unlock(chan);
02052             func(data);
02053          } else {
02054             blah = 0;
02055             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
02056             chan->timingdata = NULL;
02057             ast_channel_unlock(chan);
02058          }
02059          /* cannot 'goto done' because the channel is already unlocked */
02060          return &ast_null_frame;
02061       } else
02062          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
02063    } else
02064 #endif
02065    if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02066       /* if the AST_GENERATOR_FD is set, call the generator with args
02067        * set to -1 so it can do whatever it needs to.
02068        */
02069       void *tmp = chan->generatordata;
02070       chan->generatordata = NULL;     /* reset to let ast_write get through */
02071       chan->generator->generate(chan, tmp, -1, -1);
02072       chan->generatordata = tmp;
02073       f = &ast_null_frame;
02074       goto done;
02075    }
02076 
02077    /* Check for pending read queue */
02078    if (!AST_LIST_EMPTY(&chan->readq)) {
02079       f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list);
02080       /* Interpret hangup and return NULL */
02081       /* XXX why not the same for frames from the channel ? */
02082       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02083          ast_frfree(f);
02084          f = NULL;
02085       }
02086    } else {
02087       chan->blocker = pthread_self();
02088       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02089          if (chan->tech->exception)
02090             f = chan->tech->exception(chan);
02091          else {
02092             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02093             f = &ast_null_frame;
02094          }
02095          /* Clear the exception flag */
02096          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02097       } else if (chan->tech->read)
02098          f = chan->tech->read(chan);
02099       else
02100          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02101    }
02102 
02103    if (f) {
02104       /* if the channel driver returned more than one frame, stuff the excess
02105          into the readq for the next ast_read call (note that we can safely assume
02106          that the readq is empty, because otherwise we would not have called into
02107          the channel driver and f would be only a single frame)
02108       */
02109       if (AST_LIST_NEXT(f, frame_list)) {
02110          AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
02111          AST_LIST_NEXT(f, frame_list) = NULL;
02112       }
02113 
02114       switch (f->frametype) {
02115       case AST_FRAME_CONTROL:
02116          if (f->subclass == AST_CONTROL_ANSWER) {
02117             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02118                if (option_debug)
02119                   ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
02120                ast_frfree(f);
02121                f = &ast_null_frame;
02122             } else if (prestate == AST_STATE_UP)