func_groupcount.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * See http://www.asterisk.org for more information about
00007  * the Asterisk project. Please do not directly contact
00008  * any of the maintainers of this project for assistance;
00009  * the project provides a web site, mailing lists and IRC
00010  * channels for your use.
00011  *
00012  * This program is free software, distributed under the terms of
00013  * the GNU General Public License Version 2. See the LICENSE file
00014  * at the top of the source tree.
00015  */
00016 
00017 /*! \file
00018  *
00019  * \brief Channel group related dialplan functions
00020  * 
00021  * \ingroup functions
00022  */
00023 
00024 /*** MODULEINFO
00025    <support_level>core</support_level>
00026  ***/
00027 
00028 #include "asterisk.h"
00029 
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 431000 $")
00031 
00032 #include "asterisk/module.h"
00033 #include "asterisk/channel.h"
00034 #include "asterisk/pbx.h"
00035 #include "asterisk/utils.h"
00036 #include "asterisk/app.h"
00037 
00038 /*** DOCUMENTATION
00039    <function name="GROUP_COUNT" language="en_US">
00040       <synopsis>
00041          Counts the number of channels in the specified group.
00042       </synopsis>
00043       <syntax argsep="@">
00044          <parameter name="groupname">
00045             <para>Group name.</para>
00046          </parameter>
00047          <parameter name="category">
00048             <para>Category name</para>
00049          </parameter>
00050       </syntax>
00051       <description>
00052          <para>Calculates the group count for the specified group, or uses the
00053          channel's current group if not specified (and non-empty).</para>
00054       </description>
00055    </function>
00056    <function name="GROUP_MATCH_COUNT" language="en_US">
00057       <synopsis>
00058          Counts the number of channels in the groups matching the specified pattern.
00059       </synopsis>
00060       <syntax argsep="@">
00061          <parameter name="groupmatch" required="true">
00062             <para>A standard regular expression used to match a group name.</para>
00063          </parameter>
00064          <parameter name="category">
00065             <para>A standard regular expression used to match a category name.</para>
00066          </parameter>
00067       </syntax>
00068       <description>
00069          <para>Calculates the group count for all groups that match the specified pattern.
00070          Note: category matching is applied after matching based on group.
00071          Uses standard regular expression matching on both (see regex(7)).</para>
00072       </description>
00073    </function>
00074    <function name="GROUP" language="en_US">
00075       <synopsis>
00076          Gets or sets the channel group.
00077       </synopsis>
00078       <syntax>
00079          <parameter name="category">
00080             <para>Category name.</para>
00081          </parameter>
00082       </syntax>
00083       <description>
00084          <para><replaceable>category</replaceable> can be employed for more fine grained group management. Each channel 
00085          can only be member of exactly one group per <replaceable>category</replaceable>.</para>
00086       </description>
00087    </function>
00088    <function name="GROUP_LIST" language="en_US">
00089       <synopsis>
00090          Gets a list of the groups set on a channel.
00091       </synopsis>
00092       <syntax />
00093       <description>
00094          <para>Gets a list of the groups set on a channel.</para>
00095       </description>
00096    </function>
00097 
00098  ***/
00099 
00100 static int group_count_function_read(struct ast_channel *chan, const char *cmd,
00101                  char *data, char *buf, size_t len)
00102 {
00103    int ret = -1;
00104    int count = -1;
00105    char group[80] = "", category[80] = "";
00106 
00107    if (!chan) {
00108       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00109       return -1;
00110    }
00111 
00112    ast_app_group_split_group(data, group, sizeof(group), category,
00113               sizeof(category));
00114 
00115    /* If no group has been provided let's find one */
00116    if (ast_strlen_zero(group)) {
00117       struct ast_group_info *gi = NULL;
00118 
00119       ast_app_group_list_rdlock();
00120       for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
00121          if (gi->chan != chan)
00122             continue;
00123          if (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))
00124             break;
00125       }
00126       if (gi) {
00127          ast_copy_string(group, gi->group, sizeof(group));
00128          if (!ast_strlen_zero(gi->category))
00129             ast_copy_string(category, gi->category, sizeof(category));
00130       }
00131       ast_app_group_list_unlock();
00132    }
00133 
00134    if ((count = ast_app_group_get_count(group, category)) == -1) {
00135       ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n", ast_channel_name(chan));
00136    } else {
00137       snprintf(buf, len, "%d", count);
00138       ret = 0;
00139    }
00140 
00141    return ret;
00142 }
00143 
00144 static struct ast_custom_function group_count_function = {
00145    .name = "GROUP_COUNT",
00146    .read = group_count_function_read,
00147    .read_max = 12,
00148 };
00149 
00150 static int group_match_count_function_read(struct ast_channel *chan,
00151                   const char *cmd, char *data, char *buf,
00152                   size_t len)
00153 {
00154    char group[80] = "";
00155    char category[80] = "";
00156 
00157    ast_app_group_split_group(data, group, sizeof(group), category,
00158               sizeof(category));
00159 
00160    if (!ast_strlen_zero(group)) {
00161       int count;
00162       count = ast_app_group_match_get_count(group, category);
00163       snprintf(buf, len, "%d", count);
00164       return 0;
00165    }
00166 
00167    return -1;
00168 }
00169 
00170 static struct ast_custom_function group_match_count_function = {
00171    .name = "GROUP_MATCH_COUNT",
00172    .read = group_match_count_function_read,
00173    .read_max = 12,
00174    .write = NULL,
00175 };
00176 
00177 static int group_function_read(struct ast_channel *chan, const char *cmd,
00178                 char *data, char *buf, size_t len)
00179 {
00180    int ret = -1;
00181    struct ast_group_info *gi = NULL;
00182 
00183    if (!chan) {
00184       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00185       return -1;
00186    }
00187 
00188    ast_app_group_list_rdlock();
00189 
00190    for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
00191       if (gi->chan != chan)
00192          continue;
00193       if (ast_strlen_zero(data))
00194          break;
00195       if (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, data))
00196          break;
00197    }
00198    
00199    if (gi) {
00200       ast_copy_string(buf, gi->group, len);
00201       ret = 0;
00202    }
00203    
00204    ast_app_group_list_unlock();
00205    
00206    return ret;
00207 }
00208 
00209 static int group_function_write(struct ast_channel *chan, const char *cmd,
00210             char *data, const char *value)
00211 {
00212    char grpcat[256];
00213 
00214    if (!chan) {
00215       ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
00216       return -1;
00217    }
00218 
00219    if (!value) {
00220       return -1;
00221    }
00222 
00223    if (!ast_strlen_zero(data)) {
00224       snprintf(grpcat, sizeof(grpcat), "%s@%s", value, data);
00225    } else {
00226       ast_copy_string(grpcat, value, sizeof(grpcat));
00227    }
00228 
00229    if (ast_app_group_set_channel(chan, grpcat))
00230       ast_log(LOG_WARNING,
00231             "Setting a group requires an argument (group name)\n");
00232 
00233    return 0;
00234 }
00235 
00236 static struct ast_custom_function group_function = {
00237    .name = "GROUP",
00238    .read = group_function_read,
00239    .write = group_function_write,
00240 };
00241 
00242 static int group_list_function_read(struct ast_channel *chan, const char *cmd,
00243                 char *data, char *buf, size_t len)
00244 {
00245    struct ast_group_info *gi = NULL;
00246    char tmp1[1024] = "";
00247    char tmp2[1024] = "";
00248 
00249    if (!chan)
00250       return -1;
00251 
00252    ast_app_group_list_rdlock();
00253 
00254    for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
00255       if (gi->chan != chan)
00256          continue;
00257       if (!ast_strlen_zero(tmp1)) {
00258          ast_copy_string(tmp2, tmp1, sizeof(tmp2));
00259          if (!ast_strlen_zero(gi->category))
00260             snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, gi->group, gi->category);
00261          else
00262             snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, gi->group);
00263       } else {
00264          if (!ast_strlen_zero(gi->category))
00265             snprintf(tmp1, sizeof(tmp1), "%s@%s", gi->group, gi->category);
00266          else
00267             snprintf(tmp1, sizeof(tmp1), "%s", gi->group);
00268       }
00269    }
00270    
00271    ast_app_group_list_unlock();
00272 
00273    ast_copy_string(buf, tmp1, len);
00274 
00275    return 0;
00276 }
00277 
00278 static struct ast_custom_function group_list_function = {
00279    .name = "GROUP_LIST",
00280    .read = group_list_function_read,
00281    .write = NULL,
00282 };
00283 
00284 static int unload_module(void)
00285 {
00286    int res = 0;
00287 
00288    res |= ast_custom_function_unregister(&group_count_function);
00289    res |= ast_custom_function_unregister(&group_match_count_function);
00290    res |= ast_custom_function_unregister(&group_list_function);
00291    res |= ast_custom_function_unregister(&group_function);
00292 
00293    return res;
00294 }
00295 
00296 static int load_module(void)
00297 {
00298    int res = 0;
00299 
00300    res |= ast_custom_function_register(&group_count_function);
00301    res |= ast_custom_function_register(&group_match_count_function);
00302    res |= ast_custom_function_register(&group_list_function);
00303    res |= ast_custom_function_register(&group_function);
00304 
00305    return res;
00306 }
00307 
00308 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel group dialplan functions");

Generated on Thu Apr 16 06:27:35 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6