52 #define MAX_AUTOMONS 1500
60 unsigned int orig_end_dtmf_flag:1;
61 unsigned int video_update:1;
62 unsigned int ignore_frame_types;
71 static ast_cond_t as_cond;
73 static pthread_t asthread = AST_PTHREADT_NULL;
74 static volatile
int asexit = 0;
76 static
int as_chan_list_state;
78 static
void *autoservice_run(
void *ign)
88 struct asent *ents[MAX_AUTOMONS];
91 int i, x = 0, ms = 50;
102 ast_cond_wait(&as_cond, &aslist.lock);
107 if (x < MAX_AUTOMONS) {
109 mons[x++] = as->chan;
111 ast_log(LOG_WARNING,
"Exceeded maximum number of automatic monitoring events. Fix autoservice.c\n");
132 callid = ast_channel_callid(chan);
144 defer_frame = &hangup_frame;
153 for (i = 0; i < x; i++) {
156 if (mons[i] != chan) {
169 if (ents[i]->video_update) {
170 ast_frfree(defer_frame);
174 ents[i]->video_update = 1;
179 if (dup_f != defer_frame) {
180 ast_frfree(defer_frame);
195 asthread = AST_PTHREADT_NULL;
207 ast_debug(1,
"Thread is a user interface, not putting channel %s into autoservice\n",
208 ast_channel_name(chan));
214 if (as->chan == chan) {
233 ast_channel_lock(chan);
235 if (!as->orig_end_dtmf_flag)
237 ast_channel_unlock(chan);
242 ast_cond_signal(&as_cond);
247 if (asthread == AST_PTHREADT_NULL) {
248 if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) {
249 ast_log(LOG_WARNING,
"Unable to create autoservice thread :(\n");
254 asthread = AST_PTHREADT_NULL;
257 pthread_kill(asthread, SIGURG);
269 struct asent *as, *removed = NULL;
275 ast_debug(1,
"Thread is a user interface, not removing channel %s from autoservice\n",
276 ast_channel_name(chan));
286 chan_list_state = as_chan_list_state;
291 if (as->chan == chan) {
302 if (removed && asthread != AST_PTHREADT_NULL) {
303 pthread_kill(asthread, SIGURG);
313 while (chan_list_state == as_chan_list_state) {
320 if (!ast_channel_softhangup_internal_flag(chan)) {
324 ast_channel_lock(chan);
325 if (!as->orig_end_dtmf_flag) {
330 if (!((1 << f->
frametype) & as->ignore_frame_types)) {
335 ast_channel_unlock(chan);
359 if (as->chan == chan) {
361 as->ignore_frame_types |= (1 << ftype);
369 static void autoservice_shutdown(
void)
371 pthread_t th = asthread;
373 if (th != AST_PTHREADT_NULL) {
374 ast_cond_signal(&as_cond);
375 pthread_kill(th, SIGURG);
376 pthread_join(th, NULL);
383 ast_cond_init(&as_cond, NULL);
struct 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 millis...
Main Channel structure associated with a channel.
#define ast_frdup(fr)
Copies a frame.
#define AST_LIST_LOCK(head)
Locks a list.
void ast_autoservice_init(void)
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
Support for translation of data formats. translate.c.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
int ast_callid_threadassoc_change(ast_callid callid)
Sets what is stored in the thread storage to the given callid if it does not match what is already th...
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
void ast_autoservice_chan_hangup_peer(struct ast_channel *chan, struct ast_channel *peer)
Put chan into autoservice while hanging up peer.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
int ast_autoservice_start(struct ast_channel *chan)
Automatically service a channel for us...
struct ast_frame_subclass subclass
int ast_thread_is_user_interface(void)
Indicates whether the current thread is a user interface.
int ast_autoservice_ignore(struct ast_channel *chan, enum ast_frame_type ftype)
Ignore certain frame types.
General Asterisk PBX channel definitions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Scheduler Routines (derived from cheops)
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Asterisk internal frame definitions.
A set of macros to manage forward-linked lists.
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Core PBX routines and definitions.
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
ast_frame_type
Frame types.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
int ast_autoservice_stop(struct ast_channel *chan)
Stop servicing a channel for us...
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define ast_calloc(num, len)
A wrapper for calloc()
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Prototypes for public functions only of internal interest,.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
struct asent::@309 deferred_frames
int ast_is_deferrable_frame(const struct ast_frame *frame)
Should we keep this frame for later?
Data structure associated with a single frame of data.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to the head of a channel's frame queue.