Thu Apr 28 2011 17:15:22

Asterisk developer's documentation


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 #include "asterisk.h"
00025 
00026 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 232270 $")
00027 
00028 #include "asterisk/module.h"
00029 #include "asterisk/channel.h"
00030 #include "asterisk/pbx.h"
00031 #include "asterisk/utils.h"
00032 #include "asterisk/app.h"
00033 
00034 /*** DOCUMENTATION
00035    <function name="GROUP_COUNT" language="en_US">
00036       <synopsis>
00037          Counts the number of channels in the specified group.
00038       </synopsis>
00039       <syntax argsep="@">
00040          <parameter name="groupname">
00041             <para>Group name.</para>
00042          </parameter>
00043          <parameter name="category">
00044             <para>Category name</para>
00045          </parameter>
00046       </syntax>
00047       <description>
00048          <para>Calculates the group count for the specified group, or uses the
00049          channel's current group if not specifed (and non-empty).</para>
00050       </description>
00051    </function>
00052    <function name="GROUP_MATCH_COUNT" language="en_US">
00053       <synopsis>
00054          Counts the number of channels in the groups matching the specified pattern.
00055       </synopsis>
00056       <syntax argsep="@">
00057          <parameter name="groupmatch" required="true">
00058             <para>A standard regular expression used to match a group name.</para>
00059          </parameter>
00060          <parameter name="category">
00061             <para>Category name.</para>
00062          </parameter>
00063       </syntax>
00064       <description>
00065          <para>Calculates the group count for all groups that match the specified pattern.
00066          Uses standard regular expression matching (see regex(7)).</para>
00067       </description>
00068    </function>
00069    <function name="GROUP" language="en_US">
00070       <synopsis>
00071          Gets or sets the channel group.
00072       </synopsis>
00073       <syntax>
00074          <parameter name="category">
00075             <para>Category name.</para>
00076          </parameter>
00077       </syntax>
00078       <description>
00079          <para><replaceable>category</replaceable> can be employed for more fine grained group management. Each channel 
00080          can only be member of exactly one group per <replaceable>category</replaceable>.</para>
00081       </description>
00082    </function>
00083    <function name="GROUP_LIST" language="en_US">
00084       <synopsis>
00085          Gets a list of the groups set on a channel.
00086       </synopsis>
00087       <syntax />
00088       <description>
00089          <para>Gets a list of the groups set on a channel.</para>
00090       </description>
00091    </function>
00092 
00093  ***/
00094 
00095 static int group_count_function_read(struct ast_channel *chan, const char *cmd,
00096                  char *data, char *buf, size_t len)
00097 {
00098    int ret = -1;
00099    int count = -1;
00100    char group[80] = "", category[80] = "";
00101 
00102    ast_app_group_split_group(data, group, sizeof(group), category,
00103               sizeof(category));
00104 
00105    /* If no group has been provided let's find one */
00106    if (ast_strlen_zero(group)) {
00107       struct ast_group_info *gi = NULL;
00108 
00109       ast_app_group_list_rdlock();
00110       for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
00111          if (gi->chan != chan)
00112             continue;
00113          if (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))
00114             break;
00115       }
00116       if (gi) {
00117          ast_copy_string(group, gi->group, sizeof(group));
00118          if (!ast_strlen_zero(gi->category))
00119             ast_copy_string(category, gi->category, sizeof(category));
00120       }
00121       ast_app_group_list_unlock();
00122    }
00123 
00124    if ((count = ast_app_group_get_count(group, category)) == -1) {
00125       ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n", chan->name);
00126    } else {
00127       snprintf(buf, len, "%d", count);
00128       ret = 0;
00129    }
00130 
00131    return ret;
00132 }
00133 
00134 static struct ast_custom_function group_count_function = {
00135    .name = "GROUP_COUNT",
00136    .read = group_count_function_read,
00137 };
00138 
00139 static int group_match_count_function_read(struct ast_channel *chan,
00140                   const char *cmd, char *data, char *buf,
00141                   size_t len)
00142 {
00143    int count;
00144    char group[80] = "";
00145    char category[80] = "";
00146 
00147    ast_app_group_split_group(data, group, sizeof(group), category,
00148               sizeof(category));
00149 
00150    if (!ast_strlen_zero(group)) {
00151       count = ast_app_group_match_get_count(group, category);
00152       snprintf(buf, len, "%d", count);
00153       return 0;
00154    }
00155 
00156    return -1;
00157 }
00158 
00159 static struct ast_custom_function group_match_count_function = {
00160    .name = "GROUP_MATCH_COUNT",
00161    .read = group_match_count_function_read,
00162    .write = NULL,
00163 };
00164 
00165 static int group_function_read(struct ast_channel *chan, const char *cmd,
00166                 char *data, char *buf, size_t len)
00167 {
00168    int ret = -1;
00169    struct ast_group_info *gi = NULL;
00170    
00171    ast_app_group_list_rdlock();
00172    
00173    for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
00174       if (gi->chan != chan)
00175          continue;
00176       if (ast_strlen_zero(data))
00177          break;
00178       if (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, data))
00179          break;
00180    }
00181    
00182    if (gi) {
00183       ast_copy_string(buf, gi->group, len);
00184       ret = 0;
00185    }
00186    
00187    ast_app_group_list_unlock();
00188    
00189    return ret;
00190 }
00191 
00192 static int group_function_write(struct ast_channel *chan, const char *cmd,
00193             char *data, const char *value)
00194 {
00195    char grpcat[256];
00196 
00197    if (!value) {
00198       return -1;
00199    }
00200 
00201    if (!ast_strlen_zero(data)) {
00202       snprintf(grpcat, sizeof(grpcat), "%s@%s", value, data);
00203    } else {
00204       ast_copy_string(grpcat, value, sizeof(grpcat));
00205    }
00206 
00207    if (ast_app_group_set_channel(chan, grpcat))
00208       ast_log(LOG_WARNING,
00209             "Setting a group requires an argument (group name)\n");
00210 
00211    return 0;
00212 }
00213 
00214 static struct ast_custom_function group_function = {
00215    .name = "GROUP",
00216    .read = group_function_read,
00217    .write = group_function_write,
00218 };
00219 
00220 static int group_list_function_read(struct ast_channel *chan, const char *cmd,
00221                 char *data, char *buf, size_t len)
00222 {
00223    struct ast_group_info *gi = NULL;
00224    char tmp1[1024] = "";
00225    char tmp2[1024] = "";
00226 
00227    if (!chan)
00228       return -1;
00229 
00230    ast_app_group_list_rdlock();
00231 
00232    for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
00233       if (gi->chan != chan)
00234          continue;
00235       if (!ast_strlen_zero(tmp1)) {
00236          ast_copy_string(tmp2, tmp1, sizeof(tmp2));
00237          if (!ast_strlen_zero(gi->category))
00238             snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, gi->group, gi->category);
00239          else
00240             snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, gi->group);
00241       } else {
00242          if (!ast_strlen_zero(gi->category))
00243             snprintf(tmp1, sizeof(tmp1), "%s@%s", gi->group, gi->category);
00244          else
00245             snprintf(tmp1, sizeof(tmp1), "%s", gi->group);
00246       }
00247    }
00248    
00249    ast_app_group_list_unlock();
00250 
00251    ast_copy_string(buf, tmp1, len);
00252 
00253    return 0;
00254 }
00255 
00256 static struct ast_custom_function group_list_function = {
00257    .name = "GROUP_LIST",
00258    .read = group_list_function_read,
00259    .write = NULL,
00260 };
00261 
00262 static int unload_module(void)
00263 {
00264    int res = 0;
00265 
00266    res |= ast_custom_function_unregister(&group_count_function);
00267    res |= ast_custom_function_unregister(&group_match_count_function);
00268    res |= ast_custom_function_unregister(&group_list_function);
00269    res |= ast_custom_function_unregister(&group_function);
00270 
00271    return res;
00272 }
00273 
00274 static int load_module(void)
00275 {
00276    int res = 0;
00277 
00278    res |= ast_custom_function_register(&group_count_function);
00279    res |= ast_custom_function_register(&group_match_count_function);
00280    res |= ast_custom_function_register(&group_list_function);
00281    res |= ast_custom_function_register(&group_function);
00282 
00283    return res;
00284 }
00285 
00286 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel group dialplan functions");