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