Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:47:49 2009

## Asterisk developer's documentation

- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Directories

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