Mon Sep 18 09:12:51 2006

Asterisk developer's documentation


autoservice.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Automatic channel service routines
00022  * 
00023  */
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <sys/time.h>
00029 #include <signal.h>
00030 #include <errno.h>
00031 #include <unistd.h>
00032 #include <math.h>       /* For PI */
00033 
00034 #include "asterisk.h"
00035 
00036 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00037 
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/frame.h"
00040 #include "asterisk/sched.h"
00041 #include "asterisk/options.h"
00042 #include "asterisk/channel.h"
00043 #include "asterisk/logger.h"
00044 #include "asterisk/file.h"
00045 #include "asterisk/translate.h"
00046 #include "asterisk/manager.h"
00047 #include "asterisk/chanvars.h"
00048 #include "asterisk/linkedlists.h"
00049 #include "asterisk/indications.h"
00050 #include "asterisk/lock.h"
00051 #include "asterisk/utils.h"
00052 
00053 #define MAX_AUTOMONS 256
00054 
00055 AST_MUTEX_DEFINE_STATIC(autolock);
00056 
00057 struct asent {
00058    struct ast_channel *chan;
00059    struct asent *next;
00060 };
00061 
00062 static struct asent *aslist = NULL;
00063 static pthread_t asthread = AST_PTHREADT_NULL;
00064 
00065 static void *autoservice_run(void *ign)
00066 {
00067    struct ast_channel *mons[MAX_AUTOMONS];
00068    int x;
00069    int ms;
00070    struct ast_channel *chan;
00071    struct asent *as;
00072    struct ast_frame *f;
00073    for(;;) {
00074       x = 0;
00075       ast_mutex_lock(&autolock);
00076       as = aslist;
00077       while(as) {
00078          if (!as->chan->_softhangup) {
00079             if (x < MAX_AUTOMONS)
00080                mons[x++] = as->chan;
00081             else
00082                ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events.  Fix autoservice.c\n");
00083          }
00084          as = as->next;
00085       }
00086       ast_mutex_unlock(&autolock);
00087 
00088 /*       if (!aslist)
00089          break; */
00090       ms = 500;
00091       chan = ast_waitfor_n(mons, x, &ms);
00092       if (chan) {
00093          /* Read and ignore anything that occurs */
00094          f = ast_read(chan);
00095          if (f)
00096             ast_frfree(f);
00097       }
00098    }
00099    asthread = AST_PTHREADT_NULL;
00100    return NULL;
00101 }
00102 
00103 int ast_autoservice_start(struct ast_channel *chan)
00104 {
00105    int res = -1;
00106    struct asent *as;
00107    int needstart;
00108    ast_mutex_lock(&autolock);
00109    needstart = (asthread == AST_PTHREADT_NULL) ? 1 : 0 /* aslist ? 0 : 1 */;
00110    as = aslist;
00111    while(as) {
00112       if (as->chan == chan)
00113          break;
00114       as = as->next;
00115    }
00116    if (!as) {
00117       as = malloc(sizeof(struct asent));
00118       if (as) {
00119          memset(as, 0, sizeof(struct asent));
00120          as->chan = chan;
00121          as->next = aslist;
00122          aslist = as;
00123          res = 0;
00124          if (needstart) {
00125             if (ast_pthread_create(&asthread, NULL, autoservice_run, NULL)) {
00126                ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
00127                free(aslist);
00128                aslist = NULL;
00129                res = -1;
00130             } else
00131                pthread_kill(asthread, SIGURG);
00132          }
00133       }
00134    }
00135    ast_mutex_unlock(&autolock);
00136    return res;
00137 }
00138 
00139 int ast_autoservice_stop(struct ast_channel *chan)
00140 {
00141    int res = -1;
00142    struct asent *as, *prev;
00143    ast_mutex_lock(&autolock);
00144    as = aslist;
00145    prev = NULL;
00146    while(as) {
00147       if (as->chan == chan)
00148          break;
00149       prev = as;
00150       as = as->next;
00151    }
00152    if (as) {
00153       if (prev)
00154          prev->next = as->next;
00155       else
00156          aslist = as->next;
00157       free(as);
00158       if (!chan->_softhangup)
00159          res = 0;
00160    }
00161    if (asthread != AST_PTHREADT_NULL) 
00162       pthread_kill(asthread, SIGURG);
00163    ast_mutex_unlock(&autolock);
00164    /* Wait for it to un-block */
00165    while(ast_test_flag(chan, AST_FLAG_BLOCKING))
00166       usleep(1000);
00167    return res;
00168 }

Generated on Mon Sep 18 09:12:51 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7