App metachancount

Aus metasec wiki
Wechseln zu: Navigation, Suche
/*
 *
 * This program is free software, distributed under the terms of
 * the GNU General Public License
 *
 * Copyright (C) 2010, Lukas Ziaja / METASEC <lz@metasec.de>
 *
 */

#include "asterisk.h"

#include <asterisk.h>

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>

#include <asterisk/file.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/pbx.h>
#include <asterisk/module.h>
#include <asterisk/adsi.h>
#include <asterisk/musiconhold.h>
#include <asterisk/features.h>
#include <asterisk/options.h>
#include <asterisk/utils.h>
#include <asterisk/lock.h>


static char *app = "MetaChanCount";
static char *synopsis = "Count current Channel";
static char *descrip =
"  MetaChanCount(Technology/resource):\n"
"Matches the list of prefixes in the parameter list against channels in\n"
"state Up. If a match is found the channel is counted and\n"
"CHAN_COUNT is set. If no matching channel is found CHAN_COUNT is empty.\n";

//STANDARD_LOCAL_USER;

//LOCAL_USER_DECL;

/* Find channel matching given pattern and state, skipping our own channel.
 * Returns locked channel, which has to be unlocked using ast_mutex_unlock().
 * Returns NULL when no matching channel is found.
 */
static int find_matching_channel(struct ast_channel *chan,
        void *pattern, int chanstate)
{
        struct ast_channel *cur;
        char *pat = NULL;
        char *next_pat = NULL;
        int i=0;

        /* copy original pattern or use empty pattern if no pattern has been given*/
        if (pattern) {
                pat = alloca(strlen(pattern) + 1);
                strcpy(pat, pattern);
        } else {
                pat = "";
        }
        //ast_verbose(VERBOSE_PREFIX_4 "find_matching_channel: pattern='%s' state=%d\n", (char *)pattern, chanstate);

        /* Iterate over each part of the pattern */
        while (pat) {
                /* find pattern for next iteration, terminate current pattern */
                for (next_pat = pat; *next_pat && *next_pat != '&'; next_pat++);
                if (*next_pat == '&') {
                        *next_pat = 0;
                        next_pat++;
                } else
                        next_pat = NULL;

                /* Iterate over all channels */
                cur = ast_channel_walk_locked(NULL);
                while (cur) {

                        if ((cur != chan) && (cur->_state == chanstate) && !strncmp(pat, cur->name, strlen(pat)))
                            i++;

                        ast_mutex_unlock(&cur->lock);
                        cur = ast_channel_walk_locked(cur);

                }

                pat = next_pat;
        }

        return i;
}

static int meta_count_channel(struct ast_channel *chan, void *pattern)
{
        int ret   = 0;
        int count = 0;
        int z;

        char c_count[5];

        struct ast_module_user *u;
        u = ast_module_user_add(chan);

        count = find_matching_channel(chan, pattern, AST_STATE_UP);

        z = sprintf(c_count,"%i", count);
        ast_verbose(VERBOSE_PREFIX_3 "META_CHAN_COUNT %i \n", count );
        pbx_builtin_setvar_helper(chan, "CHAN_COUNT", c_count );
        ast_module_user_remove(u);
        return(ret);
}


static int unload_module(void)
{
        int res=0;
        ast_module_user_hangup_all();
        res = ast_unregister_application(app);
        return res;
}

static int load_module(void)
{
        return ast_register_application(app, meta_count_channel, synopsis, descrip);
}



AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "MetaChanCount" );