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
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
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 }