![]() |
Home page |
Mailing list |
Docs
Asterisk developer's documentation :: Codename Pineapple
channel.h File Reference
Definition in file channel.h.
#include "asterisk/abstract_jb.h"
#include <unistd.h>
#include <sys/poll.h>
#include "asterisk/compat.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/cdr.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/compiler.h"
Include dependency graph for channel.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Data Structures | |
| struct | ast_bridge_config |
| bridge configuration More... | |
| struct | ast_callerid |
| Structure for all kinds of caller ID identifications. More... | |
| struct | ast_channel |
| Main Channel structure associated with a channel. This is the side of it mostly used by the pbx and call management. More... | |
| struct | ast_channel_tech |
| Structure to describe a channel "technology", ie a channel driver See for examples:. More... | |
| struct | ast_datastore |
| Structure for a channel data store. More... | |
| struct | ast_datastore_info |
| Structure for a data store type. More... | |
| struct | ast_generator |
| struct | outgoing_helper |
Defines | |
| #define | AST_AGENT_FD (AST_MAX_FDS-3) |
| #define | AST_ALERT_FD (AST_MAX_FDS-1) |
| #define | AST_BRIDGE_DTMF_CHANNEL_0 (1 << 0) |
| Report DTMF on channel 0. | |
| #define | AST_BRIDGE_DTMF_CHANNEL_1 (1 << 1) |
| Report DTMF on channel 1. | |
| #define | AST_BRIDGE_IGNORE_SIGS (1 << 4) |
| Ignore all signal frames except NULL. | |
| #define | AST_BRIDGE_REC_CHANNEL_0 (1 << 2) |
| Return all voice frames on channel 0. | |
| #define | AST_BRIDGE_REC_CHANNEL_1 (1 << 3) |
| Return all voice frames on channel 1. | |
| #define | AST_CHANNEL_NAME 80 |
| #define | AST_GENERATOR_FD (AST_MAX_FDS-4) |
| #define | AST_MAX_CONTEXT 80 |
| #define | AST_MAX_EXTENSION 80 |
| #define | AST_MAX_FDS 8 |
| #define | AST_TIMING_FD (AST_MAX_FDS-2) |
| #define | CHECK_BLOCKING(c) |
| #define | CRASH do { } while(0) |
| #define | DEBUGCHAN_FLAG 0x80000000 |
| #define | FRAMECOUNT_INC(x) ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) ) |
| #define | MAX_LANGUAGE 20 |
| #define | MAX_MUSICCLASS 80 |
Typedefs | |
| typedef unsigned long long | ast_group_t |
Enumerations | |
| enum | { AST_CHAN_TP_WANTSJITTER = (1 << 0), AST_CHAN_TP_CREATESJITTER = (1 << 1) } |
| ast_channel_tech Properties More... | |
| enum | { AST_FLAG_DEFER_DTMF = (1 << 1), AST_FLAG_WRITE_INT = (1 << 2), AST_FLAG_BLOCKING = (1 << 3), AST_FLAG_ZOMBIE = (1 << 4), AST_FLAG_EXCEPTION = (1 << 5), AST_FLAG_MOH = (1 << 6), AST_FLAG_SPYING = (1 << 7), AST_FLAG_NBRIDGE = (1 << 8), AST_FLAG_IN_AUTOLOOP = (1 << 9), AST_FLAG_OUTGOING = (1 << 10), AST_FLAG_WHISPER = (1 << 11), AST_FLAG_IN_DTMF = (1 << 12), AST_FLAG_EMULATE_DTMF = (1 << 13), AST_FLAG_END_DTMF_ONLY = (1 << 14) } |
| ast_channel flags More... | |
| enum | { AST_FEATURE_PLAY_WARNING = (1 << 0), AST_FEATURE_REDIRECT = (1 << 1), AST_FEATURE_DISCONNECT = (1 << 2), AST_FEATURE_ATXFER = (1 << 3), AST_FEATURE_AUTOMON = (1 << 4), AST_FEATURE_PARKCALL = (1 << 5) } |
| ast_bridge_config flags More... | |
| enum | { AST_CDR_TRANSFER = (1 << 0), AST_CDR_FORWARD = (1 << 1), AST_CDR_CALLWAIT = (1 << 2), AST_CDR_CONFERENCE = (1 << 3) } |
| enum | { AST_SOFTHANGUP_DEV = (1 << 0), AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), AST_SOFTHANGUP_SHUTDOWN = (1 << 2), AST_SOFTHANGUP_TIMEOUT = (1 << 3), AST_SOFTHANGUP_APPUNLOAD = (1 << 4), AST_SOFTHANGUP_EXPLICIT = (1 << 5), AST_SOFTHANGUP_UNBRIDGE = (1 << 6) } |
| enum | ast_bridge_result { AST_BRIDGE_COMPLETE = 0, AST_BRIDGE_FAILED = -1, AST_BRIDGE_FAILED_NOWARN = -2, AST_BRIDGE_RETRY = -3 } |
| enum | ast_channel_adsicpe { AST_ADSI_UNKNOWN, AST_ADSI_AVAILABLE, AST_ADSI_UNAVAILABLE, AST_ADSI_OFFHOOKONLY } |
| enum | ast_channel_state { AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_OFFHOOK, AST_STATE_DIALING, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, AST_STATE_BUSY, AST_STATE_DIALING_OFFHOOK, AST_STATE_PRERING, AST_STATE_MUTE = (1 << 16) } |
| ast_channel states More... | |
| enum | channelreloadreason { CHANNEL_MODULE_LOAD, CHANNEL_MODULE_RELOAD, CHANNEL_CLI_RELOAD, CHANNEL_MANAGER_RELOAD } |
| Channel reload reasons for manager events at load or reload of configuration. More... | |
Functions | |
| int | __ast_answer (struct ast_channel *chan, unsigned int delay) |
| ast_channel * | __ast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, 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 | |
| static int | ast_add_fd (struct pollfd *pfd, int fd) |
| if fd is a valid descriptor, set *pfd with the descriptor | |
| int | ast_answer (struct ast_channel *chan) |
| Answer a channel. | |
| int | ast_autoservice_start (struct ast_channel *chan) |
| Automatically service a channel for us... | |
| int | ast_autoservice_stop (struct ast_channel *chan) |
| Stop servicing a channel for us... | |
| void | ast_begin_shutdown (int hangup) |
| Initiate system shutdown. | |
| int | ast_best_codec (int fmts) |
| Pick the best audio codec. | |
| ast_channel * | ast_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 state) attribute_pure |
| Gives the string form of a given hangup cause. | |
| void | ast_change_name (struct ast_channel *chan, char *newname) |
| Change channel name. | |
| ast_channel * | ast_channel_alloc (int needalertpipe, int state, const char *cid_num, const char *cid_name, const char *name_fmt,...) |
| Create a channel structure. | |
| int | 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_datastore * | ast_channel_datastore_alloc (const struct ast_datastore_info *info, char *uid) |
| Create a channel datastore structure. | |
| ast_datastore * | ast_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 *) |
| 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 *c0, struct ast_channel *c1) |
| Makes two channel formats compatible. | |
| int | ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone) |
| Weird function made for call transfers. | |
| ast_frame * | ast_channel_queryoption (struct ast_channel *channel, int option, void *data, int *datalen, int block) |
| 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 *channel, int subclass, const char *data, int datalen) |
| int | ast_channel_sendurl (struct ast_channel *channel, const char *url) |
| int | ast_channel_setoption (struct ast_channel *channel, 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. | |
| ast_silence_generator * | ast_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 *channel) |
| 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_channel * | ast_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. | |
| ast_variable * | ast_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. | |
| void | ast_deactivate_generator (struct ast_channel *chan) |
| int | ast_do_masquerade (struct ast_channel *chan) |
| 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 int | ast_fdisset (struct pollfd *pfds, int fd, int max, int *start) |
| Helper function for migrating select to poll. | |
| ast_channel * | ast_get_channel_by_exten_locked (const char *exten, const char *context) |
| Get channel by exten (and optionally context) and lock it. | |
| ast_channel * | ast_get_channel_by_name_locked (const char *chan) |
| Get channel by name (locks channel). | |
| ast_channel * | ast_get_channel_by_name_prefix_locked (const char *name, const int namelen) |
| Get channel by name prefix (locks channel). | |
| const struct ast_channel_tech * | ast_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. | |
| int | ast_internal_timing_enabled (struct ast_channel *chan) |
| Check if the channel can run in internal timing mode. | |
| 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 *f) |
| Queue an outgoing frame. | |
| int | ast_queue_hangup (struct ast_channel *chan) |
| Queue a hangup frame. | |
| ast_frame * | ast_read (struct ast_channel *chan) |
| Reads a frame. | |
| ast_frame * | ast_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 rtimeout, char *enders) |
| int | ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, 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_channel * | ast_request (const char *type, int format, void *data, int *status) |
| Requests a channel. | |
| ast_channel * | ast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, 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. | |
| static int | ast_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tvp) |
| Waits for activity on a group of channels. | |
| 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 *cidnum, const char *cidname, const char *ani) |
| int | ast_set_read_format (struct ast_channel *chan, int format) |
| 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 format) |
| 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) |
| 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) |
| Gives the string form of a given channel state. | |
| int | ast_str2cause (const char *name) attribute_pure |
| Convert a symbolic hangup cause to number. | |
| 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) attribute_const |
| Gives the string form of a given transfer capability. | |
| int | ast_waitfor (struct ast_channel *chan, int ms) |
| Wait for input on a channel. | |
| ast_channel * | ast_waitfor_n (struct ast_channel **chan, 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_channel * | ast_waitfor_nandfds (struct ast_channel **chan, 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 ctrlfd) |
| Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading. | |
| ast_channel * | ast_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_channel * | ast_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 *frame) |
| 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 *frame) |
| Write video frame to a channel This function writes the given frame to the indicated channel. | |
| const char * | channelreloadreason2txt (enum channelreloadreason reason) |
| Convert enum channelreloadreason to text string for manager event. | |
Variables | |
| unsigned long | global_fin |
| unsigned long | global_fout |
|
|
used by agents for pass through Definition at line 165 of file channel.h. Referenced by agent_read(). |
|
|
used for alertpipe Definition at line 163 of file channel.h. Referenced by restore_channel(). |
|
|
Report DTMF on channel 0.
Definition at line 1015 of file channel.h. Referenced by ast_generic_bridge(), iax2_bridge(), misdn_bridge(), set_config_flags(), and zt_bridge(). |
|
|
Report DTMF on channel 1.
Definition at line 1017 of file channel.h. Referenced by ast_generic_bridge(), iax2_bridge(), misdn_bridge(), set_config_flags(), and zt_bridge(). |
|
|
Ignore all signal frames except NULL.
|
|
|
Return all voice frames on channel 0.
|
|
|
Return all voice frames on channel 1.
|
|
|
Max length of an ast_channel name Definition at line 141 of file channel.h. Referenced by ast_channel_free(), ast_parse_device_state(), create_jb(), and fast_originate(). |
|
|
used by generator Definition at line 166 of file channel.h. Referenced by __ast_read(), and ast_deactivate_generator(). |
|
|
Max length of a context Definition at line 140 of file channel.h. Referenced by cleanup_stale_contexts(), and reload_config(). |
|
|
Max length of an extension Definition at line 139 of file channel.h. Referenced by ast_device_state_changed(), ast_extension_state2(), ast_hint_state_changed(), ast_ivr_menu_run_internal(), begin_dial(), do_parking_thread(), dundi_lookup_local(), get_destination(), load_config(), manager_show_dialplan_helper(), mgcp_ss(), park_add_hints(), phone_check_exception(), realtime_switch_common(), skinny_ss(), ss_thread(), and transmit_state_notify(). |
|
|
Definition at line 158 of file channel.h. Referenced by ast_channel_alloc(), ast_waitfor_nandfds(), do_parking_thread(), and update_features(). |
|
|
used for timingfd Definition at line 164 of file channel.h. Referenced by __ast_read(), agent_read(), and restore_channel(). |
|
|
Definition at line 1367 of file channel.h. Referenced by ast_sendtext(), ast_write(), phone_read(), and zt_read(). |
|
|
Definition at line 1364 of file channel.h. Referenced by agent_new(), ast_hangup(), ast_queue_frame(), ast_rtcp_read(), ast_rtp_read(), ast_sched_del(), ast_udptl_read(), create_jb(), and jb_get_and_deliver(). |
|
|
The high bit of the frame count is used as a debug marker, so increments of the counters must be done with care. Please use c->fin = FRAMECOUNT_INC(c->fin) and the same for c->fout. Definition at line 318 of file channel.h. Referenced by __ast_read(), ast_write(), handle_core_set_debug_channel(), and handle_showchan(). |
|
|
Definition at line 321 of file channel.h. Referenced by __ast_read(), and ast_write(). |
|
|
Max length of the language setting |
|
|
Max length of the music class setting |
|
|
|
|
|
ast_channel_tech Properties
Definition at line 490 of file channel.h. 00490 { 00491 /*! \brief Channels have this property if they can accept input with jitter; 00492 * i.e. most VoIP channels */ 00493 AST_CHAN_TP_WANTSJITTER = (1 << 0), 00494 /*! \brief Channels have this property if they can create jitter; 00495 * i.e. most VoIP channels */ 00496 AST_CHAN_TP_CREATESJITTER = (1 << 1), 00497 };
|
|
|
ast_channel flags
Definition at line 500 of file channel.h. 00500 { 00501 /*! Queue incoming dtmf, to be released when this flag is turned off */ 00502 AST_FLAG_DEFER_DTMF = (1 << 1), 00503 /*! write should be interrupt generator */ 00504 AST_FLAG_WRITE_INT = (1 << 2), 00505 /*! a thread is blocking on this channel */ 00506 AST_FLAG_BLOCKING = (1 << 3), 00507 /*! This is a zombie channel */ 00508 AST_FLAG_ZOMBIE = (1 << 4), 00509 /*! There is an exception pending */ 00510 AST_FLAG_EXCEPTION = (1 << 5), 00511 /*! Listening to moh XXX anthm promises me this will disappear XXX */ 00512 AST_FLAG_MOH = (1 << 6), 00513 /*! This channel is spying on another channel */ 00514 AST_FLAG_SPYING = (1 << 7), 00515 /*! This channel is in a native bridge */ 00516 AST_FLAG_NBRIDGE = (1 << 8), 00517 /*! the channel is in an auto-incrementing dialplan processor, 00518 * so when ->priority is set, it will get incremented before 00519 * finding the next priority to run */ 00520 AST_FLAG_IN_AUTOLOOP = (1 << 9), 00521 /*! This is an outgoing call */ 00522 AST_FLAG_OUTGOING = (1 << 10), 00523 /*! This channel is being whispered on */ 00524 AST_FLAG_WHISPER = (1 << 11), 00525 /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */ 00526 AST_FLAG_IN_DTMF = (1 << 12), 00527 /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 00528 * currently being emulated */ 00529 AST_FLAG_EMULATE_DTMF = (1 << 13), 00530 /*! This is set to tell the channel not to generate DTMF begin frames, and 00531 * to instead only generate END frames. */ 00532 AST_FLAG_END_DTMF_ONLY = (1 << 14), 00533 };
|
|
|
ast_bridge_config flags
Definition at line 536 of file channel.h. 00536 { 00537 AST_FEATURE_PLAY_WARNING = (1 << 0), 00538 AST_FEATURE_REDIRECT = (1 << 1), 00539 AST_FEATURE_DISCONNECT = (1 << 2), 00540 AST_FEATURE_ATXFER = (1 << 3), 00541 AST_FEATURE_AUTOMON = (1 << 4), 00542 AST_FEATURE_PARKCALL = (1 << 5), 00543 };
|
|
|
Definition at line 574 of file channel.h. 00574 { 00575 AST_CDR_TRANSFER = (1 << 0), 00576 AST_CDR_FORWARD = (1 << 1), 00577 AST_CDR_CALLWAIT = (1 << 2), 00578 AST_CDR_CONFERENCE = (1 << 3), 00579 };
|
|
|
Definition at line 581 of file channel.h. 00581 { 00582 /*! Soft hangup by device */ 00583 AST_SOFTHANGUP_DEV = (1 << 0), 00584 /*! Soft hangup for async goto */ 00585 AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), 00586 AST_SOFTHANGUP_SHUTDOWN = (1 << 2), 00587 AST_SOFTHANGUP_TIMEOUT = (1 << 3), 00588 AST_SOFTHANGUP_APPUNLOAD = (1 << 4), 00589 AST_SOFTHANGUP_EXPLICIT = (1 << 5), 00590 AST_SOFTHANGUP_UNBRIDGE = (1 << 6), 00591 };
|
|
|
Definition at line 168 of file channel.h. 00168 { 00169 AST_BRIDGE_COMPLETE = 0, 00170 AST_BRIDGE_FAILED = -1, 00171 AST_BRIDGE_FAILED_NOWARN = -2, 00172 AST_BRIDGE_RETRY = -3, 00173 };
|
|
|
Definition at line 329 of file channel.h. 00329 { 00330 AST_ADSI_UNKNOWN, 00331 AST_ADSI_AVAILABLE, 00332 AST_ADSI_UNAVAILABLE, 00333 AST_ADSI_OFFHOOKONLY, 00334 };
|
|
|
ast_channel states
Definition at line 342 of file channel.h. 00342 { 00343 /*! Channel is down and available */ 00344 AST_STATE_DOWN, 00345 /*! Channel is down, but reserved */ 00346 AST_STATE_RESERVED, 00347 /*! Channel is off hook */ 00348 AST_STATE_OFFHOOK, 00349 /*! Digits (or equivalent) have been dialed */ 00350 AST_STATE_DIALING, 00351 /*! Line is ringing */ 00352 AST_STATE_RING, 00353 /*! Remote end is ringing */ 00354 AST_STATE_RINGING, 00355 /*! Line is up */ 00356 AST_STATE_UP, 00357 /*! Line is busy */ 00358 AST_STATE_BUSY, 00359 /*! Digits (or equivalent) have been dialed while offhook */ 00360 AST_STATE_DIALING_OFFHOOK, 00361 /*! Channel has detected an incoming call and is waiting for ring */ 00362 AST_STATE_PRERING, 00363 00364 /*! Do not transmit voice data */ 00365 AST_STATE_MUTE = (1 << 16), 00366 };
|
|
|
Channel reload reasons for manager events at load or reload of configuration.
Definition at line 595 of file channel.h. 00595 { 00596 CHANNEL_MODULE_LOAD, 00597 CHANNEL_MODULE_RELOAD, 00598 CHANNEL_CLI_RELOAD, 00599 CHANNEL_MANAGER_RELOAD, 00600 };
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||||||||||
|
Definition at line 2772 of file channel.c. References ast_channel::_state, outgoing_helper::account, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, ast_frfree(), ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, outgoing_helper::parent_channel, ast_channel::priority, outgoing_helper::priority, ast_frame::subclass, and outgoing_helper::vars. Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), and ast_request_and_dial(). 02773 { 02774 int dummy_outstate; 02775 int cause = 0; 02776 struct ast_channel *chan; 02777 int res = 0; 02778 02779 if (outstate) 02780 *outstate = 0; 02781 else 02782 outstate = &dummy_outstate; /* make outstate always a valid pointer */ 02783 02784 chan = ast_request(type, format, data, &cause); 02785 if (!chan) { 02786 ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data); 02787 /* compute error and return */ 02788 if (cause == AST_CAUSE_BUSY) 02789 *outstate = AST_CONTROL_BUSY; 02790 else if (cause == AST_CAUSE_CONGESTION) 02791 *outstate = AST_CONTROL_CONGESTION; 02792 return NULL; 02793 } 02794 02795 if (oh) { 02796 if (oh->vars) 02797 ast_set_variables(chan, oh->vars); 02798 /* XXX why is this necessary, for the parent_channel perhaps ? */ 02799 if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) 02800 ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num); 02801 if (oh->parent_channel) 02802 ast_channel_inherit_variables(oh->parent_channel, chan); 02803 if (oh->account) 02804 ast_cdr_setaccount(chan, oh->account); 02805 } 02806 ast_set_callerid(chan, cid_num, cid_name, cid_num); 02807 02808 if (ast_call(chan, data, 0)) { /* ast_call failed... */ 02809 ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data); 02810 } else { 02811 res = 1; /* mark success in case chan->_state is already AST_STATE_UP */ 02812 while (timeout && chan->_state != AST_STATE_UP) { 02813 struct ast_frame *f; 02814 res = ast_waitfor(chan, timeout); 02815 if (res <= 0) /* error, timeout, or done */ 02816 break; 02817 if (timeout > -1) 02818 timeout = res; 02819 f = ast_read(chan); 02820 if (!f) { 02821 *outstate = AST_CONTROL_HANGUP; 02822 res = 0; 02823 break; 02824 } 02825 if (f->frametype == AST_FRAME_CONTROL) { 02826 switch (f->subclass) { 02827 case AST_CONTROL_RINGING: /* record but keep going */ 02828 *outstate = f->subclass; 02829 break; 02830 02831 case AST_CONTROL_BUSY: 02832 case AST_CONTROL_CONGESTION: 02833 case AST_CONTROL_ANSWER: 02834 *outstate = f->subclass; 02835 timeout = 0; /* trick to force exit from the while() */ 02836 break; 02837 02838 /* Ignore these */ 02839 case AST_CONTROL_PROGRESS: 02840 case AST_CONTROL_PROCEEDING: 02841 case AST_CONTROL_HOLD: 02842 case AST_CONTROL_UNHOLD: 02843 case AST_CONTROL_VIDUPDATE: 02844 case -1: /* Ignore -- just stopping indications */ 02845 break; 02846 02847 default: 02848 ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass); 02849 } 02850 } 02851 ast_frfree(f); 02852 } 02853 } 02854 02855 /* Final fixups */ 02856 if (oh) { 02857 if (!ast_strlen_zero(oh->context)) 02858 ast_copy_string(chan->context, oh->context, sizeof(chan->context)); 02859 if (!ast_strlen_zero(oh->exten)) 02860 ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten)); 02861 if (oh->priority) 02862 chan->priority = oh->priority; 02863 } 02864 if (chan->_state == AST_STATE_UP) 02865 *outstate = AST_CONTROL_ANSWER; 02866 02867 if (res <= 0) { 02868 if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) 02869 ast_cdr_init(chan->cdr, chan); 02870 if (chan->cdr) { 02871 char tmp[256]; 02872 snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data); 02873 ast_cdr_setapp(chan->cdr,"Dial",tmp); 02874 ast_cdr_update(chan); 02875 ast_cdr_start(chan->cdr); 02876 ast_cdr_end(chan->cdr); 02877 /* If the cause wasn't handled properly */ 02878 if (ast_cdr_disposition(chan->cdr,chan->hangupcause)) 02879 ast_cdr_failed(chan->cdr); 02880 } 02881 ast_hangup(chan); 02882 chan = NULL; 02883 } 02884 return chan; 02885 }
|
|
||||||||||||||||
|
Activate a given generator Definition at line 1694 of file channel.c. References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release. Referenced by ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), and local_ast_moh_start(). 01695 { 01696 int res = 0; 01697 01698 ast_channel_lock(chan); 01699 01700 if (chan->generatordata) { 01701 if (chan->generator && chan->generator->release) 01702 chan->generator->release(chan, chan->generatordata); 01703 chan->generatordata = NULL; 01704 } 01705 01706 ast_prod(chan); 01707 if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) { 01708 res = -1; 01709 } 01710 01711 if (!res) { 01712 ast_settimeout(chan, 160, generator_force, chan); 01713 chan->generator = gen; 01714 } 01715 01716 ast_channel_unlock(chan); 01717 01718 return res; 01719 }
|
|
|
returns number of active/allocated channels Returns number of active/allocated channels Definition at line 345 of file channel.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK. Referenced by quit_handler(). 00346 { 00347 struct ast_channel *c; 00348 int cnt = 0; 00349 AST_LIST_LOCK(&channels); 00350 AST_LIST_TRAVERSE(&channels, c, chan_list) 00351 cnt++; 00352 AST_LIST_UNLOCK(&channels); 00353 return cnt; 00354 }
|
|
||||||||||||
|
if fd is a valid descriptor, set *pfd with the descriptor
Definition at line 1286 of file channel.h. References pollfd::events, pollfd::fd, POLLIN, and POLLPRI.
|
|
|
Answer a channel.
Definition at line 1654 of file channel.c. References __ast_answer(). Referenced by __login_exec(), agi_exec_full(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), builtin_parkcall(), features_answer(), handle_answer(), park_call_exec(), park_exec(), and pbx_builtin_background(). 01655 { 01656 return __ast_answer(chan, 500); 01657 }
|
|
|
Automatically service a channel for us...
Definition at line 96 of file autoservice.c. References ast_calloc, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_RWLIST_INSERT_HEAD, AST_RWLIST_REMOVE, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, asthread, autoservice_run(), asent::chan, free, and LOG_WARNING. Referenced by ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), and feature_exec_app(). 00097 { 00098 int res = -1; 00099 struct asent *as; 00100 00101 AST_RWLIST_WRLOCK(&aslist); 00102 00103 /* Check if the channel already has autoservice */ 00104 AST_RWLIST_TRAVERSE(&aslist, as, list) { 00105 if (as->chan == chan) 00106 break; 00107 } 00108 00109 /* If not, start autoservice on channel */ 00110 if (!as && (as = ast_calloc(1, sizeof(*as)))) { 00111 as->chan = chan; 00112 AST_RWLIST_INSERT_HEAD(&aslist, as, list); 00113 res = 0; 00114 if (asthread == AST_PTHREADT_NULL) { /* need start the thread */ 00115 if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) { 00116 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00117 /* There will only be a single member in the list at this point, 00118 the one we just added. */ 00119 AST_RWLIST_REMOVE(&aslist, as, list); 00120 free(as); 00121 res = -1; 00122 } else 00123 pthread_kill(asthread, SIGURG); 00124 } 00125 } 00126 AST_RWLIST_UNLOCK(&aslist); 00127 return res; 00128 }
|
|
|
Stop servicing a channel for us...
Definition at line 130 of file autoservice.c. References ast_channel::_softhangup, AST_FLAG_BLOCKING, AST_PTHREADT_NULL, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_test_flag, asthread, asent::chan, and free. Referenced by ast_get_srv(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), feature_exec_app(), and finishup(). 00131 { 00132 int res = -1; 00133 struct asent *as; 00134 00135 AST_RWLIST_WRLOCK(&aslist); 00136 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) { 00137 if (as->chan == chan) { 00138 AST_RWLIST_REMOVE_CURRENT(&aslist, list); 00139 free(as); 00140 if (!chan->_softhangup) 00141 res = 0; 00142 break; 00143 } 00144 } 00145 AST_RWLIST_TRAVERSE_SAFE_END 00146 00147 if (asthread != AST_PTHREADT_NULL) 00148 pthread_kill(asthread, SIGURG); 00149 AST_RWLIST_UNLOCK(&aslist); 00150 00151 /* Wait for it to un-block */ 00152 while (ast_test_flag(chan, AST_FLAG_BLOCKING)) 00153 usleep(1000); 00154 return res; 00155 }
|
|
|
Initiate system shutdown. Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups Definition at line 332 of file channel.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and shutting_down. Referenced by quit_handler(). 00333 { 00334 struct ast_channel *c; 00335 shutting_down = 1; 00336 if (hangup) { 00337 AST_LIST_LOCK(&channels); 00338 AST_LIST_TRAVERSE(&channels, c, chan_list) 00339 ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN); 00340 AST_LIST_UNLOCK(&channels); 00341 } 00342 }
|
|
|
Pick the best audio codec. Okay, ulaw is used by all telephony equipment, so start with it Unless of course, you're a silly European, so then prefer ALAW Okay, well, signed linear is easy to translate into other stuff G.726 is standard ADPCM, in RFC3551 packing order G.726 is standard ADPCM, in AAL2 packing order ADPCM has great sound quality and is still pretty easy to translate Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good iLBC is not too bad Speex is free, but computationally more expensive than GSM Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough to use it G.729a is faster than 723 and slightly less expensive Down to G.723.1 which is proprietary but at least designed for voice Definition at line 559 of file channel.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs. Referenced by __login_exec(), __oh323_new(), agent_call(), ast_iax2_new(), builtin_atxfer(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), mgcp_new(), sip_new(), skinny_new(), socket_process(), and transmit_connect(). 00560 { 00561 /* This just our opinion, expressed in code. We are asked to choose 00562 the best codec to use, given no information */ 00563 int x; 00564 static int prefs[] = 00565 { 00566 /*! Okay, ulaw is used by all telephony equipment, so start with it */ 00567 AST_FORMAT_ULAW, 00568 /*! Unless of course, you're a silly European, so then prefer ALAW */ 00569 AST_FORMAT_ALAW, 00570 /*! Okay, well, signed linear is easy to translate into other stuff */ 00571 AST_FORMAT_SLINEAR, 00572 /*! G.726 is standard ADPCM, in RFC3551 packing order */ 00573 AST_FORMAT_G726, 00574 /*! G.726 is standard ADPCM, in AAL2 packing order */ 00575 AST_FORMAT_G726_AAL2, 00576 /*! ADPCM has great sound quality and is still pretty easy to translate */ 00577 AST_FORMAT_ADPCM, 00578 /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to 00579 translate and sounds pretty good */ 00580 AST_FORMAT_GSM, 00581 /*! iLBC is not too bad */ 00582 AST_FORMAT_ILBC, 00583 /*! Speex is free, but computationally more expensive than GSM */ 00584 AST_FORMAT_SPEEX, 00585 /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough 00586 to use it */ 00587 AST_FORMAT_LPC10, 00588 /*! G.729a is faster than 723 and slightly less expensive */ 00589 AST_FORMAT_G729A, 00590 /*! Down to G.723.1 which is proprietary but at least designed for voice */ 00591 AST_FORMAT_G723_1, 00592 }; 00593 00594 /* Strip out video */ 00595 fmts &= AST_FORMAT_AUDIO_MASK; 00596 00597 /* Find the first preferred codec in the format given */ 00598 for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++) 00599 if (fmts & prefs[x]) 00600 return prefs[x]; 00601 ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts); 00602 return 0; 00603 }
|
|
|
Find bridged channel.
Definition at line 3589 of file channel.c. References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech. Referenced by __zt_exception(), agents_show(), agents_show_online(), ast_channel_masquerade(), attempt_transfer(), console_transfer(), create_jb(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response_answer(), handle_response_invite(), handle_showchan(), local_attended_transfer(), mgcp_hangup(), mgcp_ss(), schedule_delivery(), sip_read(), socket_process(), ss_thread(), zt_handle_event(), and zt_hangup(). 03590 { 03591 struct ast_channel *bridged; 03592 bridged = chan->_bridge; 03593 if (bridged && bridged->tech->bridged_channel) 03594 bridged = bridged->tech->bridged_channel(chan, bridged); 03595 return bridged; 03596 }
|
|
||||||||||||||||
|
Make a call.
Definition at line 2941 of file channel.c. References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, and ast_channel::tech. Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), begin_dial(), and features_call(). 02942 { 02943 /* Place an outgoing call, but don't wait any longer than timeout ms before returning. 02944 If the remote end does not answer within the timeout, then do NOT hang up, but 02945 return anyway. */ 02946 int res = -1; 02947 /* Stop if we're a zombie or need a soft hangup */ 02948 ast_channel_lock(chan); 02949 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) { 02950 if (chan->tech->call) 02951 res = chan->tech->call(chan, addr, timeout); 02952 ast_set_flag(chan, AST_FLAG_OUTGOING); 02953 } 02954 ast_channel_unlock(chan); 02955 return res; 02956 }
|
|
|
Cancel a shutdown in progress. Cancels an existing shutdown and returns to normal operation Definition at line 357 of file channel.c. References shutting_down. Referenced by handle_abort_halt(). 00358 { 00359 shutting_down = 0; 00360 }
|
|
|
Gives the string form of a given hangup cause.
Definition at line 477 of file channel.c. Referenced by __transmit_response(), ast_hangup(), and transmit_request_with_auth(). 00478 { 00479 int x; 00480 00481 for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) { 00482 if (causes[x].cause == cause) 00483 return causes[x].desc; 00484 } 00485 00486 return "Unknown"; 00487 }
|
|
||||||||||||
|
Change channel name.
Definition at line 3162 of file channel.c. References ast_string_field_set, EVENT_FLAG_CALL, manager_event, and name. 03163 { 03164 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid); 03165 ast_string_field_set(chan, name, newname); 03166 }
|
|
||||||||||||||||||||||||||||
|
Create a channel structure.
Definition at line 611 of file channel.c. References ast_calloc, ast_log(), AST_MAX_FDS, ast_string_field_init, free, LOG_WARNING, sched_context_create(), and shutting_down. Referenced by __oh323_new(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_park_call(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), builtin_atxfer(), check_goto_on_transfer(), gtalk_new(), iax_park(), jingle_new(), local_new(), mgcp_new(), nbs_new(), oss_new(), phone_new(), sip_new(), sip_park(), and skinny_new(). 00612 { 00613 struct ast_channel *tmp; 00614 int x; 00615 int flags; 00616 struct varshead *headp; 00617 va_list ap1, ap2; 00618 00619 /* If shutting down, don't allocate any new channels */ 00620 if (shutting_down) { 00621 ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n"); 00622 return NULL; 00623 } 00624 00625 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) 00626 return NULL; 00627 00628 if (!(tmp->sched = sched_context_create())) { 00629 ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n"); 00630 free(tmp); 00631 return NULL; 00632 } 00633 00634 ast_string_field_init(tmp, 128); 00635 00636 /* Don't bother initializing the last two FD here, because they 00637 will *always* be set just a few lines down (AST_TIMING_FD, 00638 AST_ALERT_FD). */ 00639 for (x = 0; x < AST_MAX_FDS - 2; x++) 00640 tmp->fds[x] = -1; 00641 00642 #ifdef HAVE_ZAPTEL 00643 tmp->timingfd = open("/dev/zap/timer", O_RDWR); 00644 if (tmp->timingfd > -1) { 00645 /* Check if timing interface supports new 00646 ping/pong scheme */ 00647 flags = 1; 00648 if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags)) 00649 needqueue = 0; 00650 } 00651 #else 00652 tmp->timingfd = -1; 00653 #endif 00654 00655 if (needqueue) { 00656 if (pipe(tmp->alertpipe)) { 00657 ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n"); 00658 ast_string_field_free_pools(tmp); 00659 free(tmp); 00660 return NULL; 00661 } else { 00662 flags = fcntl(tmp->alertpipe[0], F_GETFL); 00663 fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK); 00664 flags = fcntl(tmp->alertpipe[1], F_GETFL); 00665 fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK); 00666 } 00667 } else /* Make sure we've got it done right if they don't */ 00668 tmp->alertpipe[0] = tmp->alertpipe[1] = -1; 00669 00670 /* Always watch the alertpipe */ 00671 tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0]; 00672 /* And timing pipe */ 00673 tmp->fds[AST_TIMING_FD] = tmp->timingfd; 00674 ast_string_field_set(tmp, name, "**Unknown**"); 00675 00676 /* Initial state */ 00677 tmp->_state = state; 00678 00679 tmp->streamid = -1; 00680 00681 tmp->fin = global_fin; 00682 tmp->fout = global_fout; 00683 00684 if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) { 00685 ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 00686 ast_atomic_fetchadd_int(&uniqueint, 1)); 00687 } else { 00688 ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 00689 (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1)); 00690 } 00691 00692 if (!ast_strlen_zero(name_fmt)) { 00693 /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call. 00694 * And they all use slightly different formats for their name string. 00695 * This means, to set the name here, we have to accept variable args, and call the string_field_build from here. 00696 * This means, that the stringfields must have a routine that takes the va_lists directly, and 00697 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list. 00698 * This new function was written so this can be accomplished. 00699 */ 00700 va_start(ap1, name_fmt); 00701 va_start(ap2, name_fmt); 00702 ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2); 00703 va_end(ap1); 00704 va_end(ap2); 00705 00706 /* and now, since the channel structure is built, and has its name, let's call the 00707 * manager event generator with this Newchannel event. This is the proper and correct 00708 * place to make this call, but you sure do have to pass a lot of data into this func 00709 * to do it here! 00710 */ 00711 manager_event(EVENT_FLAG_CALL, "Newchannel", 00712 "Channel: %s\r\n" 00713 "State: %s\r\n" 00714 "CallerIDNum: %s\r\n" 00715 "CallerIDName: %s\r\n" 00716 "Uniqueid: %s\r\n", 00717 tmp->name, ast_state2str(state), 00718 S_OR(cid_num, "<unknown>"), 00719 S_OR(cid_name, "<unknown>"), 00720 tmp->uniqueid); 00721 } 00722 00723 headp = &tmp->varshead; 00724 AST_LIST_HEAD_INIT_NOLOCK(headp); 00725 00726 ast_mutex_init(&tmp->lock); 00727 00728 AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); 00729 00730 strcpy(tmp->context, "default"); 00731 strcpy(tmp->exten, "s"); 00732 tmp->priority = 1; 00733 00734 ast_string_field_set(tmp, language, defaultlanguage); 00735 tmp->amaflags = ast_default_amaflags; 00736 ast_string_field_set(tmp, accountcode, ast_default_accountcode); 00737 00738 tmp->tech = &null_tech; 00739 00740 AST_LIST_LOCK(&channels); 00741 AST_LIST_INSERT_HEAD(&channels, tmp, chan_list); 00742 AST_LIST_UNLOCK(&channels); 00743 00744 return tmp; 00745 }
|
|
||||||||||||||||||||||||
|
Bridge two channels together. Bridge two channels together
Definition at line 3788 of file channel.c. References ast_channel::_bridge, AST_BRIDGE_COMPLETE, ast_check_hangup_locked(), AST_FEATURE_PLAY_WARNING, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_tvadd(), ast_tvsub(), bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, LOG_WARNING, manager_event, ast_channel::nativeformats, ast_channel_tech::send_digit_begin, and ast_channel::tech. Referenced by ast_bridge_call(). 03790 { 03791 struct ast_channel *who = NULL; 03792 enum ast_bridge_result res = AST_BRIDGE_COMPLETE; 03793 int nativefailed=0; 03794 int firstpass; 03795 int o0nativeformats; 03796 int o1nativeformats; 03797 long time_left_ms=0; 03798 struct timeval nexteventts = { 0, }; 03799 char caller_warning = 0; 03800 char callee_warning = 0; 03801 03802 if (c0->_bridge) { 03803 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03804 c0->name, c0->_bridge->name); 03805 return -1; 03806 } 03807 if (c1->_bridge) { 03808 ast_log(LOG_WARNING, "%s is already in a bridge with %s\n", 03809 c1->name, c1->_bridge->name); 03810 return -1; 03811 } 03812 03813 /* Stop if we're a zombie or need a soft hangup */ 03814 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03815 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) 03816 return -1; 03817 03818 *fo = NULL; 03819 firstpass = config->firstpass; 03820 config->firstpass = 0; 03821 03822 if (ast_tvzero(config->start_time)) 03823 config->start_time = ast_tvnow(); 03824 time_left_ms = config->timelimit; 03825 03826 caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING); 03827 callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING); 03828 03829 if (config->start_sound && firstpass) { 03830 if (caller_warning) 03831 bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000); 03832 if (callee_warning) 03833 bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000); 03834 } 03835 03836 /* Keep track of bridge */ 03837 c0->_bridge = c1; 03838 c1->_bridge = c0; 03839 03840 /* \todo XXX here should check that cid_num is not NULL */ 03841 manager_event(EVENT_FLAG_CALL, "Link", 03842 "Channel1: %s\r\n" 03843 "Channel2: %s\r\n" 03844 "Uniqueid1: %s\r\n" 03845 "Uniqueid2: %s\r\n" 03846 "CallerID1: %s\r\n" 03847 "CallerID2: %s\r\n", 03848 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03849 03850 o0nativeformats = c0->nativeformats; 03851 o1nativeformats = c1->nativeformats; 03852 03853 if (config->feature_timer) { 03854 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000)); 03855 } else if (config->timelimit) { 03856 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03857 if (caller_warning || callee_warning) 03858 nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000)); 03859 } 03860 03861 if (!c0->tech->send_digit_begin) 03862 ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY); 03863 if (!c1->tech->send_digit_begin) 03864 ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY); 03865 03866 for (/* ever */;;) { 03867 struct timeval now = { 0, }; 03868 int to; 03869 03870 to = -1; 03871 03872 if (!ast_tvzero(nexteventts)) { 03873 now = ast_tvnow(); 03874 to = ast_tvdiff_ms(nexteventts, now); 03875 if (to <= 0) { 03876 if (!config->timelimit) { 03877 res = AST_BRIDGE_COMPLETE; 03878 break; 03879 } 03880 to = 0; 03881 } 03882 } 03883 03884 if (config->timelimit) { 03885 time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time); 03886 if (time_left_ms < to) 03887 to = time_left_ms; 03888 03889 if (time_left_ms <= 0) { 03890 if (caller_warning && config->end_sound) 03891 bridge_playfile(c0, c1, config->end_sound, 0); 03892 if (callee_warning && config->end_sound) 03893 bridge_playfile(c1, c0, config->end_sound, 0); 03894 *fo = NULL; 03895 if (who) 03896 *rc = who; 03897 res = 0; 03898 break; 03899 } 03900 03901 if (!to) { 03902 if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) { 03903 int t = (time_left_ms + 500) / 1000; /* round to nearest second */ 03904 if (caller_warning) 03905 bridge_playfile(c0, c1, config->warning_sound, t); 03906 if (callee_warning) 03907 bridge_playfile(c1, c0, config->warning_sound, t); 03908 } 03909 if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) 03910 nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000)); 03911 else 03912 nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000)); 03913 } 03914 } 03915 03916 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) { 03917 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03918 c0->_softhangup = 0; 03919 if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03920 c1->_softhangup = 0; 03921 c0->_bridge = c1; 03922 c1->_bridge = c0; 03923 if (option_debug) 03924 ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n"); 03925 continue; 03926 } 03927 03928 /* Stop if we're a zombie or need a soft hangup */ 03929 if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) || 03930 ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) { 03931 *fo = NULL; 03932 if (who) 03933 *rc = who; 03934 res = 0; 03935 if (option_debug) 03936 ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n", 03937 c0->name, c1->name, 03938 ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03939 ast_check_hangup(c0) ? "Yes" : "No", 03940 ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No", 03941 ast_check_hangup(c1) ? "Yes" : "No"); 03942 break; 03943 } 03944 03945 if (c0->tech->bridge && 03946 (config->timelimit == 0) && 03947 (c0->tech->bridge == c1->tech->bridge) && 03948 !nativefailed && !c0->monitor && !c1->monitor && 03949 !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) && 03950 !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) { 03951 /* Looks like they share a bridge method and nothing else is in the way */ 03952 ast_set_flag(c0, AST_FLAG_NBRIDGE); 03953 ast_set_flag(c1, AST_FLAG_NBRIDGE); 03954 if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) { 03955 /* \todo XXX here should check that cid_num is not NULL */ 03956 manager_event(EVENT_FLAG_CALL, "Unlink", 03957 "Channel1: %s\r\n" 03958 "Channel2: %s\r\n" 03959 "Uniqueid1: %s\r\n" 03960 "Uniqueid2: %s\r\n" 03961 "CallerID1: %s\r\n" 03962 "CallerID2: %s\r\n", 03963 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 03964 if (option_debug) 03965 ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name); 03966 03967 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03968 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03969 03970 if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) 03971 continue; 03972 03973 c0->_bridge = NULL; 03974 c1->_bridge = NULL; 03975 03976 return res; 03977 } else { 03978 ast_clear_flag(c0, AST_FLAG_NBRIDGE); 03979 ast_clear_flag(c1, AST_FLAG_NBRIDGE); 03980 } 03981 switch (res) { 03982 case AST_BRIDGE_RETRY: 03983 continue; 03984 default: 03985 if (option_verbose > 2) 03986 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n", 03987 c0->name, c1->name); 03988 /* fallthrough */ 03989 case AST_BRIDGE_FAILED_NOWARN: 03990 nativefailed++; 03991 break; 03992 } 03993 } 03994 03995 if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) || 03996 (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) && 03997 !(c0->generator || c1->generator)) { 03998 if (ast_channel_make_compatible(c0, c1)) { 03999 ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name); 04000 /* \todo XXX here should check that cid_num is not NULL */ 04001 manager_event(EVENT_FLAG_CALL, "Unlink", 04002 "Channel1: %s\r\n" 04003 "Channel2: %s\r\n" 04004 "Uniqueid1: %s\r\n" 04005 "Uniqueid2: %s\r\n" 04006 "CallerID1: %s\r\n" 04007 "CallerID2: %s\r\n", 04008 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 04009 return AST_BRIDGE_FAILED; 04010 } 04011 o0nativeformats = c0->nativeformats; 04012 o1nativeformats = c1->nativeformats; 04013 } 04014 res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts); 04015 if (res != AST_BRIDGE_RETRY) 04016 break; 04017 } 04018 04019 ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY); 04020 ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY); 04021 04022 c0->_bridge = NULL; 04023 c1->_bridge = NULL; 04024 04025 /* \todo XXX here should check that cid_num is not NULL */ 04026 manager_event(EVENT_FLAG_CALL, "Unlink", 04027 "Channel1: %s\r\n" 04028 "Channel2: %s\r\n" 04029 "Uniqueid1: %s\r\n" 04030 "Uniqueid2: %s\r\n" 04031 "CallerID1: %s\r\n" 04032 "CallerID2: %s\r\n", 04033 c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num); 04034 if (option_debug) 04035 ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name); 04036 04037 return res; 04038 }
|
|
||||||||||||
|
Compare a offset with the settings of when to hang a channel up.
Definition at line 377 of file channel.c. References ast_channel::whentohangup. 00378 { 00379 time_t whentohangup; 00380 00381 if (chan->whentohangup == 0) { 00382 return (offset == 0) ? 0 : -1; 00383 } else { 00384 if (offset == 0) /* XXX why is this special ? */ 00385 return (1); 00386 else { 00387 whentohangup = offset + time (NULL); 00388 if (chan->whentohangup < whentohangup) 00389 return (1); 00390 else if (chan->whentohangup == whentohangup) 00391 return (0); 00392 else 00393 return (-1); 00394 } 00395 } 00396 }
|
|
||||||||||||
|
Add a datastore to a channel.
Definition at line 1142 of file channel.c. References AST_LIST_INSERT_HEAD. 01143 { 01144 int res = 0; 01145 01146 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 01147 01148 return res; 01149 }
|
|
||||||||||||
|
Create a channel datastore structure.
Definition at line 1098 of file channel.c. References ast_calloc, ast_strdup, and ast_datastore::info. 01099 { 01100 struct ast_datastore *datastore = NULL; 01101 01102 /* Make sure we at least have type so we can identify this */ 01103 if (info == NULL) { 01104 return NULL; 01105 } 01106 01107 /* Allocate memory for datastore and clear it */ 01108 datastore = ast_calloc(1, sizeof(*datastore)); 01109 if (datastore == NULL) { 01110 return NULL; 01111 } 01112 01113 datastore->info = info; 01114 01115 datastore->uid = ast_strdup(uid); 01116 01117 return datastore; 01118 }
|
|
||||||||||||||||
|
Find a datastore on a channel.
Definition at line 1169 of file channel.c. References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_datastore::info, and ast_datastore::uid. 01170 { 01171 struct ast_datastore *datastore = NULL; 01172 01173 if (info == NULL) 01174 return NULL; 01175 01176 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) { 01177 if (datastore->info == info) { 01178 if (uid != NULL && datastore->uid != NULL) { 01179 if (!strcasecmp(uid, datastore->uid)) { 01180 /* Matched by type AND uid */ 01181 break; 01182 } 01183 } else { 01184 /* Matched by type at least */ 01185 break; 01186 } 01187 } 01188 } 01189 AST_LIST_TRAVERSE_SAFE_END 01190 01191 return datastore; 01192 }
|
|
|
Free a channel datastore structure.
Definition at line 1120 of file channel.c. References ast_datastore::data, ast_datastore_info::destroy, free, ast_datastore::info, and ast_datastore::uid. Referenced by ast_channel_free(). 01121 { 01122 int res = 0; 01123 01124 /* Using the destroy function (if present) destroy the data */ 01125 if (datastore->info->destroy != NULL && datastore->data != NULL) { 01126 datastore->info->destroy(datastore->data); 01127 datastore->data = NULL; 01128 } 01129 01130 /* Free allocated UID memory */ 01131 if (datastore->uid != NULL) { 01132 free(datastore->uid); 01133 datastore->uid = NULL; 01134 } 01135 01136 /* Finally free memory used by ourselves */ 01137 free(datastore); 01138 01139 return res; 01140 }
|
|
||||||||||||
|
Remove a datastore from a channel.
Definition at line 1151 of file channel.c. References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END. 01152 { 01153 struct ast_datastore *datastore2 = NULL; 01154 int res = -1; 01155 01156 /* Find our position and remove ourselves */ 01157 AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) { 01158 if (datastore2 == datastore) { 01159 AST_LIST_REMOVE_CURRENT(&chan->datastores, entry); 01160 res = 0; 01161 break; 01162 } 01163 } 01164 AST_LIST_TRAVERSE_SAFE_END 01165 01166 return res; 01167 }
|
|
|
Set defer DTMF flag on channel. Defer DTMF so that you only read things like hangups and audio. Returns non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred Definition at line 839 of file channel.c. References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag. Referenced by find_cache(). 00840 { 00841 int pre = 0; 00842 00843 if (chan) { 00844 pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF); 00845 ast_set_flag(chan, AST_FLAG_DEFER_DTMF); 00846 } 00847 return pre; 00848 }
|
|
||||||||||||
|
Bridge two channels together (early). Bridge two channels together (early)
Definition at line 3778 of file channel.c. References ast_channel_tech::early_bridge, and ast_channel::tech. 03779 { 03780 /* Make sure we can early bridge, if not error out */ 03781 if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge))) 03782 return -1; 03783 03784 return c0->tech->early_bridge(c0, c1); 03785 }
|
|
|
Free a channel structure.
Definition at line 1018 of file channel.c. References ast_channel::alertpipe, ast_channel_datastore_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_channel_whisper_stop(), ast_device_state_changed_literal(), ast_frfree(), ast_jb_destroy(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_moh_cleanup(), ast_mutex_destroy(), ast_string_field_free_pools, ast_translator_free_path(), ast_var_delete(), ast_channel::cid, free, free_cid(), ast_channel::lock, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, name, ast_channel::pbx, ast_channel::readtrans, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::varshead, ast_channel::whisper, and ast_channel::writetrans. Referenced by agent_cleanup(), agent_new(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), and local_new(). 01019 { 01020 int fd; 01021 struct ast_var_t *vardata; 01022 struct ast_frame *f; 01023 struct varshead *headp; 01024 struct ast_datastore *datastore = NULL; 01025 char name[AST_CHANNEL_NAME]; 01026 01027 headp=&chan->varshead; 01028 01029 AST_LIST_LOCK(&channels); 01030 AST_LIST_REMOVE(&channels, chan, chan_list); 01031 /* Lock and unlock the channel just to be sure nobody 01032 has it locked still */ 01033 ast_channel_lock(chan); 01034 ast_channel_unlock(chan); 01035 if (chan->tech_pvt) { 01036 ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name); 01037 free(chan->tech_pvt); 01038 } 01039 01040 if (chan->sched) 01041 sched_context_destroy(chan->sched); 01042 01043 ast_copy_string(name, chan->name, sizeof(name)); 01044 01045 /* Stop monitoring */ 01046 if (chan->monitor) 01047 chan->monitor->stop( chan, 0 ); 01048 01049 /* If there is native format music-on-hold state, free it */ 01050 if (chan->music_state) 01051 ast_moh_cleanup(chan); 01052 01053 /* if someone is whispering on the channel, stop them */ 01054 if (chan->whisper) 01055 ast_channel_whisper_stop(chan); 01056 01057 /* Free translators */ 01058 if (chan->readtrans) 01059 ast_translator_free_path(chan->readtrans); 01060 if (chan->writetrans) 01061 ast_translator_free_path(chan->writetrans); 01062 if (chan->pbx) 01063 ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name); 01064 free_cid(&chan->cid); 01065 ast_mutex_destroy(&chan->lock); 01066 /* Close pipes if appropriate */ 01067 if ((fd = chan->alertpipe[0]) > -1) 01068 close(fd); 01069 if ((fd = chan->alertpipe[1]) > -1) 01070 close(fd); 01071 if ((fd = chan->timingfd) > -1) 01072 close(fd); 01073 while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list))) 01074 ast_frfree(f); 01075 01076 /* Get rid of each of the data stores on the channel */ 01077 while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry))) 01078 /* Free the data store */ 01079 ast_channel_datastore_free(datastore); 01080 AST_LIST_HEAD_INIT_NOLOCK(&chan->datastores); 01081 01082 /* loop over the variables list, freeing all data and deleting list items */ 01083 /* no need to lock the list, as the channel is already locked */ 01084 01085 while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries))) 01086 ast_var_delete(vardata); 01087 01088 /* Destroy the jitterbuffer */ 01089 ast_jb_destroy(chan); 01090 01091 ast_string_field_free_pools(chan); 01092 free(chan); 01093 AST_LIST_UNLOCK(&channels); 01094 01095 ast_device_state_changed_literal(name); 01096 }
|
|
||||||||||||
|
Inherits channel variable from parent to child channel.
Definition at line 3168 of file channel.c. References AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), LOG_DEBUG, option_debug, and ast_channel::varshead. Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), and begin_dial(). 03169 { 03170 struct ast_var_t *current, *newvar; 03171 const char *varname; 03172 03173 AST_LIST_TRAVERSE(&parent->varshead, current, entries) { 03174 int vartype = 0; 03175 03176 varname = ast_var_full_name(current); 03177 if (!varname) 03178 continue; 03179 03180 if (varname[0] == '_') { 03181 vartype = 1; 03182 if (varname[1] == '_') 03183 vartype = 2; 03184 } 03185 03186 switch (vartype) { 03187 case 1: 03188 newvar = ast_var_assign(&varname[1], ast_var_value(current)); 03189 if (newvar) { 03190 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 03191 if (option_debug) 03192 ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar)); 03193 } 03194 break; 03195 case 2: 03196 newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current)); 03197 if (newvar) { 03198 AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries); 03199 if (option_debug) 03200 ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar)); 03201 } 03202 break; 03203 default: 03204 if (option_debug) 03205 ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current)); 03206 break; 03207 } 03208 } 03209 }
|
|
||||||||||||
|
Makes two channel formats compatible.
Definition at line 3080 of file channel.c. References ast_channel_make_compatible_helper(). Referenced by check_compat(), and park_exec(). 03081 { 03082 /* Some callers do not check return code, and we must try to set all call legs correctly */ 03083 int rc = 0; 03084 03085 /* Set up translation from the chan to the peer */ 03086 rc = ast_channel_make_compatible_helper(chan, peer); 03087 03088 if (rc < 0) 03089 return rc; 03090 03091 /* Set up translation from the peer to the chan */ 03092 rc = ast_channel_make_compatible_helper(peer, chan); 03093 03094 return rc; 03095 }
|
|
||||||||||||
|
Weird function made for call transfers.
Definition at line 3097 of file channel.c. References ast_channel::_bridge, ast_bridged_channel(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_log(), ast_null_frame, ast_queue_frame(), LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and option_debug. Referenced by ast_async_goto(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), handle_invite_replaces(), iax_park(), misdn_transfer_bc(), and sip_park(). 03098 { 03099 int res = -1; 03100 struct ast_channel *final_orig = original, *final_clone = clone; 03101 03102 ast_channel_lock(original); 03103 while (ast_channel_trylock(clone)) { 03104 ast_channel_unlock(original); 03105 usleep(1); 03106 ast_channel_lock(original); 03107 } 03108 03109 /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent) 03110 and if so, we don't really want to masquerade it, but its proxy */ 03111 if (original->_bridge && (original->_bridge != ast_bridged_channel(original))) 03112 final_orig = original->_bridge; 03113 03114 if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone))) 03115 final_clone = clone->_bridge; 03116 03117 if ((final_orig != original) || (final_clone != clone)) { 03118 ast_channel_lock(final_orig); 03119 while (ast_channel_trylock(final_clone)) { 03120 ast_channel_unlock(final_orig); 03121 usleep(1); 03122 ast_channel_lock(final_orig); 03123 } 03124 ast_channel_unlock(clone); 03125 ast_channel_unlock(original); 03126 original = final_orig; 03127 clone = final_clone; 03128 } 03129 03130 if (original == clone) { 03131 ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name); 03132 ast_channel_unlock(clone); 03133 ast_channel_unlock(original); 03134 return -1; 03135 } 03136 03137 if (option_debug) 03138 ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n", 03139 clone->name, original->name); 03140 if (original->masq) { 03141 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 03142 original->masq->name, original->name); 03143 } else if (clone->masqr) { 03144 ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n", 03145 clone->name, clone->masqr->name); 03146 } else { 03147 original->masq = clone; 03148 clone->masqr = original; 03149 ast_queue_frame(original, &ast_null_frame); 03150 ast_queue_frame(clone, &ast_null_frame); 03151 if (option_debug) 03152 ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name); 03153 res = 0; 03154 } 03155 03156 ast_channel_unlock(clone); 03157 ast_channel_unlock(original); 03158 03159 return res; 03160 }
|
|
||||||||||||||||||||||||
|
Query the value of an option, optionally blocking until a reply is received Works similarly to setoption except only reads the options. |
|
|
Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
Definition at line 399 of file channel.c. References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_verbose(), LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2. Referenced by load_module(), and unload_module(). 00400 { 00401 struct chanlist *chan; 00402 00403 AST_LIST_LOCK(&channels); 00404 00405 AST_LIST_TRAVERSE(&backends, chan, list) { 00406 if (!strcasecmp(tech->type, chan->tech->type)) { 00407 ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type); 00408 AST_LIST_UNLOCK(&channels); 00409 return -1; 00410 } 00411 } 00412 00413 if (!(chan = ast_calloc(1, sizeof(*chan)))) { 00414 AST_LIST_UNLOCK(&channels); 00415 return -1; 00416 } 00417 chan->tech = tech; 00418 AST_LIST_INSERT_HEAD(&backends, chan, list); 00419 00420 if (option_debug) 00421 ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description); 00422 00423 if (option_verbose > 1) 00424 ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type, 00425 chan->tech->description); 00426 00427 AST_LIST_UNLOCK(&channels); 00428 return 0; 00429 }
|
|
||||||||||||||||||||
|
Send HTML or URL on link. Returns 0 on success or -1 on failure Definition at line 3036 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech. Referenced by agent_sendhtml(), and ast_channel_sendurl(). 03037 { 03038 if (chan->tech->send_html) 03039 return chan->tech->send_html(chan, subclass, data, datalen); 03040 return -1; 03041 }
|
|
||||||||||||
|
Send URL on link. Returns 0 on success or -1 on failure Definition at line 3043 of file channel.c. References ast_channel_sendhtml(), and AST_HTML_URL. 03044 { 03045 return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1); 03046 }
|
|
||||||||||||||||||||||||
|
Sets an option on a channel.
Definition at line 4041 of file channel.c. References ast_log(), LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech. Referenced by ast_bridge_call(), handle_tddmode(), and zt_hangup(). 04042 { 04043 int res; 04044 04045 if (chan->tech->setoption) { 04046 res = chan->tech->setoption(chan, option, data, datalen); 04047 if (res < 0) 04048 return res; 04049 } else { 04050 errno = ENOSYS; 04051 return -1; 04052 } 04053 if (block) { 04054 /* XXX Implement blocking -- just wait for our option frame reply, discarding 04055 intermediate packets. XXX */ 04056 ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n"); 04057 return -1; 04058 } 04059 return 0; 04060 }
|
|
||||||||||||
|
Set when to hang a channel up.
Definition at line 369 of file channel.c. References ast_null_frame, ast_queue_frame(), and ast_channel::whentohangup. Referenced by action_timeout(). 00370 { 00371 chan->whentohangup = offset ? time(NULL) + offset : 0; 00372 ast_queue_frame(chan, &ast_null_frame); 00373 return; 00374 }
|
|
|
Starts a silence generator on the given channel.
The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation. Definition at line 4489 of file channel.c. References ast_activate_generator(), ast_calloc, AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), free, LOG_ERROR, ast_silence_generator::old_write_format, silence_generator, and ast_channel::writeformat. 04490 { 04491 struct ast_silence_generator *state; 04492 04493 if (!(state = ast_calloc(1, sizeof(*state)))) { 04494 return NULL; 04495 } 04496 04497 state->old_write_format = chan->writeformat; 04498 04499 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) { 04500 ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n"); 04501 free(state); 04502 return NULL; 04503 } 04504 04505 ast_activate_generator(chan, &silence_generator, state); 04506 04507 if (option_debug) 04508 ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name); 04509 04510 return state; 04511 }
|
|
||||||||||||
|
Stops a previously-started silence generator on the given channel.
Definition at line 4513 of file channel.c. References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_ERROR, and ast_silence_generator::old_write_format. 04514 { 04515 if (!state) 04516 return; 04517 04518 ast_deactivate_generator(chan); 04519 04520 if (option_debug) 04521 ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name); 04522 04523 if (ast_set_write_format(chan, state->old_write_format) < 0) 04524 ast_log(LOG_ERROR, "Could not return write format to its original state\n"); 04525 04526 free(state); 04527 }
|
|
|
Returns 0 if channel does not support HTML or non-zero if it does Definition at line 3031 of file channel.c. References ast_channel_tech::send_html, and ast_channel::tech.
|
|
|
Unset defer DTMF flag on channel. Undo defer. ast_read will return any dtmf characters that were queued Definition at line 851 of file channel.c. References ast_clear_flag, and AST_FLAG_DEFER_DTMF. Referenced by find_cache(). 00852 { 00853 if (chan) 00854 ast_clear_flag(chan, AST_FLAG_DEFER_DTMF); 00855 }
|
|
|
Unregister a channel technology.
Definition at line 431 of file channel.c. References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), free, LOG_DEBUG, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2. Referenced by __unload_module(), and unload_module(). 00432 { 00433 struct chanlist *chan; 00434 00435 if (option_debug) 00436 ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type); 00437 00438 AST_LIST_LOCK(&channels); 00439 00440 AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) { 00441 if (chan->tech == tech) { 00442 AST_LIST_REMOVE_CURRENT(&backends, list); 00443 free(chan); 00444 if (option_verbose > 1) 00445 ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type); 00446 break; 00447 } 00448 } 00449 AST_LIST_TRAVERSE_SAFE_END 00450 00451 AST_LIST_UNLOCK(&channels); 00452 }
|
|
|
Browse channels in use Browse the channels currently in use.
Definition at line 938 of file channel.c. References channel_find_locked(). Referenced by action_status(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_complete_channels(), ast_pickup_call(), complete_ch_helper(), group_show_channels(), handle_chanlist(), handle_core_set_debug_channel(), and moh_on_off(). 00939 { 00940 return channel_find_locked(prev, NULL, 0, NULL, NULL); 00941 }
|
|
||||||||||||
|
Feed an audio frame into the whisper buffer on a channel.
Definition at line 4732 of file channel.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_slinfactory_feed(), ast_channel_whisper_buffer::lock, ast_channel_whisper_buffer::sf, and ast_channel::whisper. 04733 { 04734 if (!chan->whisper) 04735 return -1; 04736 04737 ast_mutex_lock(&chan->whisper->lock); 04738 ast_slinfactory_feed(&chan->whisper->sf, f); 04739 ast_mutex_unlock(&chan->whisper->lock); 04740 04741 return 0; 04742 }
|
|
|
Begin 'whispering' onto a channel.
Definition at line 4717 of file channel.c. References ast_calloc, AST_FLAG_WHISPER, ast_mutex_init(), ast_set_flag, ast_slinfactory_init(), ast_channel_whisper_buffer::lock, ast_channel_whisper_buffer::sf, and ast_channel::whisper. 04718 { 04719 if (chan->whisper) 04720 return -1; 04721 04722 if (!(chan->whisper = ast_calloc(1, sizeof(*chan->whisper)))) 04723 return -1; 04724 04725 ast_mutex_init(&chan->whisper->lock); 04726 ast_slinfactory_init(&chan->whisper->sf); 04727 ast_set_flag(chan, AST_FLAG_WHISPER); 04728 04729 return 0; 04730 }
|
|
|
Stop 'whispering' onto a channel.
Definition at line 4744 of file channel.c. References ast_clear_flag, AST_FLAG_WHISPER, AST_FORMAT_SLINEAR, ast_mutex_destroy(), ast_set_write_format(), ast_slinfactory_destroy(), ast_translator_free_path(), free, ast_channel_whisper_buffer::original_format, ast_channel_whisper_buffer::path, ast_channel::whisper, and ast_channel::writeformat. Referenced by ast_channel_free(). 04745 { 04746 if (!chan->whisper) 04747 return; 04748 04749 ast_clear_flag(chan, AST_FLAG_WHISPER); 04750 if (chan->whisper->path) 04751 ast_translator_free_path(chan->whisper->path); 04752 if (chan->whisper->original_format && chan->writeformat == AST_FORMAT_SLINEAR) 04753 ast_set_write_format(chan, chan->whisper->original_format); 04754 ast_slinfactory_destroy(&chan->whisper->sf); 04755 ast_mutex_destroy(&chan->whisper->lock); 04756 free(chan->whisper); 04757 chan->whisper = NULL; 04758 }
|
|
|
return an ast_variable list of channeltypes
Definition at line 171 of file channel.c. References AST_LIST_TRAVERSE, ast_variable_new(), ast_channel_tech::description, chanlist::tech, ast_channel_tech::type, and var. 00172 { 00173 struct chanlist *cl; 00174 struct ast_variable *var=NULL, *prev = NULL; 00175 AST_LIST_TRAVERSE(&backends, cl, list) { 00176 if (prev) { 00177 if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description))) 00178 prev = prev->next; 00179 } else { 00180 var = ast_variable_new(cl->tech->type, cl->tech->description); 00181 prev = var; 00182 } 00183 } 00184 return var; 00185 }
|
|
|
Check to see if a channel is needing hang up.
Definition at line 308 of file channel.c. References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_channel::tech_pvt, and ast_channel::whentohangup. Referenced by __ast_answer(), __ast_read(), ast_call(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate_data(), ast_readstring_full(), ast_recvtext(), ast_sendtext(), ast_transfer(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), handle_sendimage(), and zt_setoption(). 00309 { 00310 if (chan->_softhangup) /* yes if soft hangup flag set */ 00311 return 1; 00312 if (!chan->tech_pvt) /* yes if no technology private data */ 00313 return 1; 00314 if (!chan->whentohangup) /* no if no hangup scheduled */ 00315 return 0; 00316 if (chan->whentohangup > time(NULL)) /* no if hangup time has not come yet. */ 00317 return 0; 00318 chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */ 00319 return 1; 00320 }
|
|
|
Deactivate an active generator Definition at line 1659 of file channel.c. References ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), ast_channel::fds, ast_channel::generator, ast_channel::generatordata, and ast_generator::release. Referenced by __ast_read(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_tonepair_stop(), ast_write(), generator_force(), local_ast_moh_stop(), and moh_on_off(). 01660 { 01661 ast_channel_lock(chan); 01662 if (chan->generatordata) { 01663 if (chan->generator && chan->generator->release) 01664 chan->generator->release(chan, chan->generatordata); 01665 chan->generatordata = NULL; 01666 chan->generator = NULL; 01667 chan->fds[AST_GENERATOR_FD] = -1; 01668 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 01669 ast_settimeout(chan, 0, NULL, NULL); 01670 } 01671 ast_channel_unlock(chan); 01672 }
|
|
|
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.
Definition at line 3249 of file channel.c. References ast_channel::_state, ast_channel::alertpipe, ast_channel_lock, AST_LIST_FIRST, AST_LIST_HEAD_SET_NOLOCK, ast_log(), ast_state2str(), ast_string_field_set, EVENT_FLAG_CALL, free_translation(), ast_channel::lock, LOG_DEBUG, manager_event, ast_channel::masq, ast_channel::masqr, name, option_debug, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat. Referenced by __ast_read(), ast_async_goto(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), iax_park(), sip_park(), and sip_park_thread(). 03250 { 03251 int x,i; 03252 int res=0; 03253 int origstate; 03254 struct ast_frame *cur; 03255 const struct ast_channel_tech *t; 03256 void *t_pvt; 03257 struct ast_callerid tmpcid; 03258 struct ast_channel *clone = original->masq; 03259 struct ast_channel_spy_list *spy_list = NULL; 03260 struct ast_channel_spy *spy = NULL; 03261 int rformat = original->readformat; 03262 int wformat = original->writeformat; 03263 char newn[100]; 03264 char orig[100]; 03265 char masqn[100]; 03266 char zombn[100]; 03267 03268 if (option_debug > 3) 03269 ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n", 03270 clone->name, clone->_state, original->name, original->_state); 03271 03272 manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n", 03273 clone->name, ast_state2str(clone->_state), original->name, ast_state2str(original->_state)); 03274 03275 /* XXX This is a seriously wacked out operation. We're essentially putting the guts of 03276 the clone channel into the original channel. Start by killing off the original 03277 channel's backend. I'm not sure we're going to keep this function, because 03278 while the features are nice, the cost is very high in terms of pure nastiness. XXX */ 03279 03280 /* We need the clone's lock, too */ 03281 ast_channel_lock(clone); 03282 03283 if (option_debug > 1) 03284 ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock); 03285 03286 /* Having remembered the original read/write formats, we turn off any translation on either 03287 one */ 03288 free_translation(clone); 03289 free_translation(original); 03290 03291 03292 /* Unlink the masquerade */ 03293 original->masq = NULL; 03294 clone->masqr = NULL; 03295 03296 /* Save the original name */ 03297 ast_copy_string(orig, original->name, sizeof(orig)); 03298 /* Save the new name */ 03299 ast_copy_string(newn, clone->name, sizeof(newn)); 03300 /* Create the masq name */ 03301 snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn); 03302 03303 /* Copy the name from the clone channel */ 03304 ast_string_field_set(original, name, newn); 03305 03306 /* Mangle the name of the clone channel */ 03307 ast_string_field_set(clone, name, masqn); 03308 03309 /* Notify any managers of the change, first the masq then the other */ 03310 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid); 03311 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid); 03312 03313 /* Swap the technologies */ 03314 t = original->tech; 03315 original->tech = clone->tech; 03316 clone->tech = t; 03317 03318 t_pvt = original->tech_pvt; 03319 original->tech_pvt = clone->tech_pvt; 03320 clone->tech_pvt = t_pvt; 03321 03322 /* Swap the readq's */ 03323 cur = AST_LIST_FIRST(&original->readq); 03324 AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq)); 03325 AST_LIST_HEAD_SET_NOLOCK(&clone->readq, cur); 03326 03327 /* Swap the alertpipes */ 03328 for (i = 0; i < 2; i++) { 03329 x = original->alertpipe[i]; 03330 original->alertpipe[i] = clone->alertpipe[i]; 03331 clone->alertpipe[i] = x; 03332 } 03333 03334 /* Swap the raw formats */ 03335 x = original->rawreadformat; 03336 original->rawreadformat = clone->rawreadformat; 03337 clone->rawreadformat = x; 03338 x = original->rawwriteformat; 03339 original->rawwriteformat = clone->rawwriteformat; 03340 clone->rawwriteformat = x; 03341 03342 /* Swap the spies */ 03343 spy_list = original->spies; 03344 original->spies = clone->spies; 03345 clone->spies = spy_list; 03346 03347 /* Update channel on respective spy lists if present */ 03348 if (original->spies) { 03349 AST_LIST_TRAVERSE(&original->spies->list, spy, list) { 03350 ast_mutex_lock(&spy->lock); 03351 spy->chan = original; 03352 ast_mutex_unlock(&spy->lock); 03353 } 03354 } 03355 if (clone->spies) { 03356 AST_LIST_TRAVERSE(&clone->spies->list, spy, list) { 03357 ast_mutex_lock(&spy->lock); 03358 spy->chan = clone; 03359 ast_mutex_unlock(&spy->lock); 03360 } 03361 } 03362 03363 /* Save any pending frames on both sides. Start by counting 03364 * how many we're going to need... */ 03365 x = 0; 03366 if (original->alertpipe[1] > -1) { 03367 AST_LIST_TRAVERSE(&clone->readq, cur, frame_list) 03368 x++; 03369 } 03370 03371 /* If we had any, prepend them to the ones already in the queue, and 03372 * load up the alertpipe */ 03373 if (AST_LIST_FIRST(&clone->readq)) { 03374 AST_LIST_INSERT_TAIL(&clone->readq, AST_LIST_FIRST(&original->readq), frame_list); 03375 AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq)); 03376 AST_LIST_HEAD_SET_NOLOCK(&clone->readq, NULL); 03377 for (i = 0; i < x; i++) 03378 write(original->alertpipe[1], &x, sizeof(x)); 03379 } 03380 03381 clone->_softhangup = AST_SOFTHANGUP_DEV; 03382 03383 03384 /* And of course, so does our current state. Note we need not 03385 call ast_setstate since the event manager doesn't really consider 03386 these separate. We do this early so that the clone has the proper 03387 state of the original channel. */ 03388 origstate = original->_state; 03389 original->_state = clone->_state; 03390 clone->_state = origstate; 03391 03392 if (clone->tech->fixup){ 03393 res = clone->tech->fixup(original, clone); 03394 if (res) 03395 ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name); 03396 } 03397 03398 /* Start by disconnecting the original's physical side */ 03399 if (clone->tech->hangup) 03400 res = clone->tech->hangup(clone); 03401 if (res) { 03402 ast_log(LOG_WARNING, "Hangup failed! Strange things may happen!\n"); 03403 ast_channel_unlock(clone); 03404 return -1; 03405 } 03406 03407 snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); 03408 /* Mangle the name of the clone channel */ 03409 ast_string_field_set(clone, name, zombn); 03410 manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid); 03411 03412 /* Update the type. */ 03413 t_pvt = original->monitor; 03414 original->monitor = clone->monitor; 03415 clone->monitor = t_pvt; 03416 03417 /* Keep the same language. */ 03418 ast_string_field_set(original, language, clone->language); 03419 /* Copy the FD's other than the generator fd */ 03420 for (x = 0; x < AST_MAX_FDS; x++) { 03421 if (x != AST_GENERATOR_FD) 03422 original->fds[x] = clone->fds[x]; 03423 } 03424 03425 /* move any whisperer over */ 03426 ast_channel_whisper_stop(original); 03427 if (ast_test_flag(clone, AST_FLAG_WHISPER)) { 03428 original->whisper = clone->whisper; 03429 ast_set_flag(original, AST_FLAG_WHISPER); 03430 clone->whisper = NULL; 03431 ast_clear_flag(clone, AST_FLAG_WHISPER); 03432 } 03433 03434 /* Move data stores over */ 03435 if (AST_LIST_FIRST(&clone->datastores)) 03436 AST_LIST_INSERT_TAIL(&original->datastores, AST_LIST_FIRST(&clone->datastores), entry); 03437 AST_LIST_HEAD_INIT_NOLOCK(&clone->datastores); 03438 03439 clone_variables(original, clone); 03440 AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead); 03441 /* Presense of ADSI capable CPE follows clone */ 03442 original->adsicpe = clone->adsicpe; 03443 /* Bridge remains the same */ 03444 /* CDR fields remain the same */ 03445 /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 03446 /* Application and data remain the same */ 03447 /* Clone exception becomes real one, as with fdno */ 03448 ast_copy_flags(original, clone, AST_FLAG_EXCEPTION); 03449 original->fdno = clone->fdno; 03450 /* Schedule context remains the same */ 03451 /* Stream stuff stays the same */ 03452 /* Keep the original state. The fixup code will need to work with it most likely */ 03453 03454 /* Just swap the whole structures, nevermind the allocations, they'll work themselves 03455 out. */ 03456 tmpcid = original->cid; 03457 original->cid = clone->cid; 03458 clone->cid = tmpcid; 03459 03460 /* Restore original timing file descriptor */ 03461 original->fds[AST_TIMING_FD] = original->timingfd; 03462 03463 /* Our native formats are different now */ 03464 original->nativeformats = clone->nativeformats; 03465 03466 /* Context, extension, priority, app data, jump table, remain the same */ 03467 /* pvt switches. pbx stays the same, as does next */ 03468 03469 /* Set the write format */ 03470 ast_set_write_format(original, wformat); 03471 03472 /* Set the read format */ 03473 ast_set_read_format(original, rformat); 03474 03475 /* Copy the music class */ 03476 ast_string_field_set(original, musicclass, clone->musicclass); 03477 03478 if (option_debug) 03479 ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat); 03480 03481 /* Okay. Last thing is to let the channel driver know about all this mess, so he 03482 can fix up everything as best as possible */ 03483 if (original->tech->fixup) { 03484 res = original->tech->fixup(clone, original); 03485 if (res) { 03486 ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n", 03487 original->tech->type, original->name); 03488 ast_channel_unlock(clone); 03489 return -1; 03490 } 03491 } else 03492 ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)! Bad things may happen.\n", 03493 original->tech->type, original->name); 03494 03495 /* Now, at this point, the "clone" channel is totally F'd up. We mark it as 03496 a zombie so nothing tries to touch it. If it's already been marked as a 03497 zombie, then free it now (since it already is considered invalid). */ 03498 if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) { 03499 if (option_debug) 03500 ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name); 03501 ast_channel_unlock(clone); 03502 manager_event(EVENT_FLAG_CALL, "Hangup", 03503 "Channel: %s\r\n" 03504 "Uniqueid: %s\r\n" 03505 "Cause: %d\r\n" 03506 "Cause-txt: %s\r\n", 03507 clone->name, 03508 clone->uniqueid, 03509 clone->hangupcause, 03510 ast_cause2str(clone->hangupcause) 03511 ); 03512 ast_channel_free(clone); 03513 } else { 03514 if (option_debug) 03515 ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name); 03516 ast_set_flag(clone, AST_FLAG_ZOMBIE); 03517 ast_queue_frame(clone, &ast_null_frame); 03518 ast_channel_unlock(clone); 03519 } 03520 03521 /* Signal any blocker */ 03522 if (ast_test_flag(original, AST_FLAG_BLOCKING)) 03523 pthread_kill(original->blocker, SIGURG); 03524 if (option_debug) 03525 ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state); 03526 return 0; 03527 }
|
|
||||||||||||||||||||
|
Helper function for migrating select to poll.
Definition at line 1294 of file channel.h. References pollfd::revents. 01295 { 01296 int x; 01297 int dummy=0; 01298 01299 if (fd < 0) 01300 return 0; 01301 if (!start) 01302 start = &dummy; 01303 for (x = *start; x<max; x++) 01304 if (pfds[x].fd == fd) { 01305 if (x == *start) 01306 (*start)++; 01307 return pfds[x].revents; 01308 } 01309 return 0; 01310 }
|
|
||||||||||||
|
Get channel by exten (and optionally context) and lock it.
Definition at line 963 of file channel.c. References channel_find_locked(). 00964 { 00965 return channel_find_locked(NULL, NULL, 0, context, exten); 00966 }
|
|
|
Get channel by name (locks channel).
Definition at line 944 of file channel.c. References channel_find_locked(). Referenced by action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), change_monitor_action(), do_pause_or_unpause(), handle_channelstatus(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_showchan(), handle_softhangup(), manager_park(), pbx_builtin_importvar(), start_monitor_action(), and stop_monitor_action(). 00945 { 00946 return channel_find_locked(NULL, name, 0, NULL, NULL); 00947 }
|
|
||||||||||||
|
Get channel by name prefix (locks channel).
Definition at line 950 of file channel.c. References channel_find_locked(). Referenced by ast_parse_device_state(). 00951 { 00952 return channel_find_locked(NULL, name, namelen, NULL, NULL); 00953 }
|
|
|
Get a channel technology structure by name.
Definition at line 454 of file channel.c. References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), LOG_WARNING, chanlist::tech, and ast_channel_tech::type. Referenced by ast_device_state(). 00455 { 00456 struct chanlist *chanls; 00457 const struct ast_channel_tech *ret = NULL; 00458 00459 if (AST_LIST_LOCK(&channels)) { 00460 ast_log(LOG_WARNING, "Unable to lock channel tech list\n"); 00461 return NULL; 00462 } 00463 00464 AST_LIST_TRAVERSE(&backends, chanls, list) { 00465 if (!strcasecmp(name, chanls->tech->type)) { 00466 ret = chanls->tech; 00467 break; 00468 } 00469 } 00470 00471 AST_LIST_UNLOCK(&channels); 00472 00473 return ret; 00474 }
|
|
|
Definition at line 4214 of file channel.c. References ast_log(), ast_strdupa, group, LOG_ERROR, LOG_WARNING, and strsep(). Referenced by _parse(), build_device(), build_gateway(), build_peer(), and read_agent_config(). 04215 { 04216 char *piece; 04217 char *c; 04218 int start=0, finish=0, x; 04219 ast_group_t group = 0; 04220 04221 c = ast_strdupa(s); 04222 04223 while ((piece = strsep(&c, ","))) { 04224 if (sscanf(piece, "%d-%d", &start, &finish) == 2) { 04225 /* Range */ 04226 } else if (sscanf(piece, "%d", &start)) { 04227 /* Just one */ 04228 finish = start; 04229 } else { 04230 ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece); 04231 continue; 04232 } 04233 for (x = start; x <= finish; x++) { 04234 if ((x > 63) || (x < 0)) { 04235 ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x); 04236 } else 04237 group |= ((ast_group_t) 1 << x); 04238 } 04239 } 04240 return group; 04241 }
|
|
|
Hang up a channel.
Definition at line 1528 of file channel.c. References ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, CRASH, detach_spies(), EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, option_debug, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, and ast_channel::vstream. Referenced by __ast_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), ast_async_goto(), ast_bridge_call_thread(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial(), builtin_atxfer(), check_compat(), do_parking_thread(), features_hangup(), gtalk_new(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), hangup_chan(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_attended_transfer(), local_hangup(), mgcp_new(), mgcp_ss(), monitor_dial(), nbs_new(), oss_new(), park_exec(), phone_new(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), and zt_handle_event(). 01529 { 01530 int res = 0; 01531 01532 /* Don't actually hang up a channel that will masquerade as someone else, or 01533 if someone is going to masquerade as us */ 01534 ast_channel_lock(chan); 01535 01536 detach_spies(chan); /* get rid of spies */ 01537 01538 if (chan->masq) { 01539 if (ast_do_masquerade(chan)) 01540 ast_log(LOG_WARNING, "Failed to perform masquerade\n"); 01541 } 01542 01543 if (chan->masq) { 01544 ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name); 01545 ast_channel_unlock(chan); 01546 return 0; 01547 } 01548 /* If this channel is one which will be masqueraded into something, 01549 mark it as a zombie already, so we know to free it later */ 01550 if (chan->masqr) { 01551 ast_set_flag(chan, AST_FLAG_ZOMBIE); 01552 ast_channel_unlock(chan); 01553 return 0; 01554 } 01555 free_translation(chan); 01556 /* Close audio stream */ 01557 if (chan->stream) { 01558 ast_closestream(chan->stream); 01559 chan->stream = NULL; 01560 } 01561 /* Close video stream */ 01562 if (chan->vstream) { 01563 ast_closestream(chan->vstream); 01564 chan->vstream = NULL; 01565 } 01566 if (chan->sched) { 01567 sched_context_destroy(chan->sched); 01568 chan->sched = NULL; 01569 } 01570 01571 if (chan->generatordata) /* Clear any tone stuff remaining */ 01572 if (chan->generator && chan->generator->release) 01573 chan->generator->release(chan, chan->generatordata); 01574 chan->generatordata = NULL; 01575 chan->generator = NULL; 01576 if (chan->cdr) { /* End the CDR if it hasn't already */ 01577 ast_cdr_end(chan->cdr); 01578 ast_cdr_detach(chan->cdr); /* Post and Free the CDR */ 01579 chan->cdr = NULL; 01580 } 01581 if (ast_test_flag(chan, AST_FLAG_BLOCKING)) { 01582 ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd " 01583 "is blocked by thread %ld in procedure %s! Expect a failure\n", 01584 (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc); 01585 CRASH; 01586 } 01587 if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) { 01588 if (option_debug) 01589 ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name); 01590 if (chan->tech->hangup) 01591 res = chan->tech->hangup(chan); 01592 } else { 01593 if (option_debug) 01594 ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name); 01595 } 01596 01597 ast_channel_unlock(chan); 01598 manager_event(EVENT_FLAG_CALL, "Hangup", 01599 "Channel: %s\r\n" 01600 "Uniqueid: %s\r\n" 01601 "Cause: %d\r\n" 01602 "Cause-txt: %s\r\n", 01603 chan->name, 01604 chan->uniqueid, 01605 chan->hangupcause, 01606 ast_cause2str(chan->hangupcause) 01607 ); 01608 ast_channel_free(chan); 01609 return res; 01610 }
|
|
||||||||||||
|
Indicates condition of channel.
Definition at lin |