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

Generated on Sat Jun 12 16:40:57 2004 for Asterisk by doxygen 1.3.7