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 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 = (pthread_t) -1;
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 = (pthread_t) -1;
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 == (pthread_t) -1) ? 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 != (pthread_t) -1) 
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 Fri Oct 31 07:05:05 2003 for Asterisk by doxygen 1.3.4