Main Page | Alphabetical List | Data Structures | Directories | 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 Wed Mar 16 20:08:34 2005 for Asterisk by  doxygen 1.4.0