00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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>
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 static ast_mutex_t autolock = AST_MUTEX_INITIALIZER;
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
00073
00074 ms = 500;
00075 chan = ast_waitfor_n(mons, x, &ms);
00076 if (chan) {
00077
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 ;
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
00149 while(chan->blocking)
00150 usleep(1000);
00151 return res;
00152 }