Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

autoservice.c

Go to the documentation of this file.
00001 /* 00002 * Asterisk -- A telephony toolkit for Linux. 00003 * 00004 * Automatic channel service routines 00005 * 00006 * Copyright (C) 1999, Mark Spencer 00007 * 00008 * Mark Spencer <markster@linux-support.net> 00009 * 00010 * This program is free software, distributed under the terms of 00011 * the GNU General Public License 00012 */ 00013 00014 #include <stdio.h> 00015 #include <stdlib.h> 00016 #include <string.h> 00017 #include <sys/time.h> 00018 #include <signal.h> 00019 #include <errno.h> 00020 #include <unistd.h> 00021 #include <math.h> /* For PI */ 00022 #include <asterisk/pbx.h> 00023 #include <asterisk/frame.h> 00024 #include <asterisk/sched.h> 00025 #include <asterisk/options.h> 00026 #include <asterisk/channel.h> 00027 #include <asterisk/channel_pvt.h> 00028 #include <asterisk/logger.h> 00029 #include <asterisk/file.h> 00030 #include <asterisk/translate.h> 00031 #include <asterisk/manager.h> 00032 #include <asterisk/chanvars.h> 00033 #include <asterisk/linkedlists.h> 00034 #include <asterisk/indications.h> 00035 #include <asterisk/lock.h> 00036 #include <asterisk/utils.h> 00037 00038 #define MAX_AUTOMONS 256 00039 00040 AST_MUTEX_DEFINE_STATIC(autolock); 00041 00042 struct asent { 00043 struct ast_channel *chan; 00044 struct asent *next; 00045 }; 00046 00047 static struct asent *aslist = NULL; 00048 static pthread_t asthread = AST_PTHREADT_NULL; 00049 00050 static void *autoservice_run(void *ign) 00051 { 00052 struct ast_channel *mons[MAX_AUTOMONS]; 00053 int x; 00054 int ms; 00055 struct ast_channel *chan; 00056 struct asent *as; 00057 struct ast_frame *f; 00058 for(;;) { 00059 x = 0; 00060 ast_mutex_lock(&autolock); 00061 as = aslist; 00062 while(as) { 00063 if (!as->chan->_softhangup) { 00064 if (x < MAX_AUTOMONS) 00065 mons[x++] = as->chan; 00066 else 00067 ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events. Fix autoservice.c\n"); 00068 } 00069 as = as->next; 00070 } 00071 ast_mutex_unlock(&autolock); 00072 00073 /* if (!aslist) 00074 break; */ 00075 ms = 500; 00076 chan = ast_waitfor_n(mons, x, &ms); 00077 if (chan) { 00078 /* Read and ignore anything that occurs */ 00079 f = ast_read(chan); 00080 if (f) 00081 ast_frfree(f); 00082 } 00083 } 00084 asthread = AST_PTHREADT_NULL; 00085 return NULL; 00086 } 00087 00088 int ast_autoservice_start(struct ast_channel *chan) 00089 { 00090 int res = -1; 00091 struct asent *as; 00092 int needstart; 00093 ast_mutex_lock(&autolock); 00094 needstart = (asthread == AST_PTHREADT_NULL) ? 1 : 0 /* aslist ? 0 : 1 */; 00095 as = aslist; 00096 while(as) { 00097 if (as->chan == chan) 00098 break; 00099 as = as->next; 00100 } 00101 if (!as) { 00102 as = malloc(sizeof(struct asent)); 00103 if (as) { 00104 memset(as, 0, sizeof(struct asent)); 00105 as->chan = chan; 00106 as->next = aslist; 00107 aslist = as; 00108 res = 0; 00109 if (needstart) { 00110 if (ast_pthread_create(&asthread, NULL, autoservice_run, NULL)) { 00111 ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n"); 00112 free(aslist); 00113 aslist = NULL; 00114 res = -1; 00115 } else 00116 pthread_kill(asthread, SIGURG); 00117 } 00118 } 00119 } 00120 ast_mutex_unlock(&autolock); 00121 return res; 00122 } 00123 00124 int ast_autoservice_stop(struct ast_channel *chan) 00125 { 00126 int res = -1; 00127 struct asent *as, *prev; 00128 ast_mutex_lock(&autolock); 00129 as = aslist; 00130 prev = NULL; 00131 while(as) { 00132 if (as->chan == chan) 00133 break; 00134 prev = as; 00135 as = as->next; 00136 } 00137 if (as) { 00138 if (prev) 00139 prev->next = as->next; 00140 else 00141 aslist = as->next; 00142 free(as); 00143 if (!chan->_softhangup) 00144 res = 0; 00145 } 00146 if (asthread != AST_PTHREADT_NULL) 00147 pthread_kill(asthread, SIGURG); 00148 ast_mutex_unlock(&autolock); 00149 /* Wait for it to un-block */ 00150 while(chan->blocking) 00151 usleep(1000); 00152 return res; 00153 }

Generated on Fri Sep 24 21:03:46 2004 for Asterisk by doxygen 1.3.8