Wed Jan 8 2020 09:49:47

Asterisk developer's documentation


func_groupcount.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16 
17 /*! \file
18  *
19  * \brief Channel group related dialplan functions
20  *
21  * \ingroup functions
22  */
23 
24 /*** MODULEINFO
25  <support_level>core</support_level>
26  ***/
27 
28 #include "asterisk.h"
29 
30 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 411313 $")
31 
32 #include "asterisk/module.h"
33 #include "asterisk/channel.h"
34 #include "asterisk/pbx.h"
35 #include "asterisk/utils.h"
36 #include "asterisk/app.h"
37 
38 /*** DOCUMENTATION
39  <function name="GROUP_COUNT" language="en_US">
40  <synopsis>
41  Counts the number of channels in the specified group.
42  </synopsis>
43  <syntax argsep="@">
44  <parameter name="groupname">
45  <para>Group name.</para>
46  </parameter>
47  <parameter name="category">
48  <para>Category name</para>
49  </parameter>
50  </syntax>
51  <description>
52  <para>Calculates the group count for the specified group, or uses the
53  channel's current group if not specifed (and non-empty).</para>
54  </description>
55  </function>
56  <function name="GROUP_MATCH_COUNT" language="en_US">
57  <synopsis>
58  Counts the number of channels in the groups matching the specified pattern.
59  </synopsis>
60  <syntax argsep="@">
61  <parameter name="groupmatch" required="true">
62  <para>A standard regular expression used to match a group name.</para>
63  </parameter>
64  <parameter name="category">
65  <para>A standard regular expression used to match a category name.</para>
66  </parameter>
67  </syntax>
68  <description>
69  <para>Calculates the group count for all groups that match the specified pattern.
70  Note: category matching is applied after matching based on group.
71  Uses standard regular expression matching on both (see regex(7)).</para>
72  </description>
73  </function>
74  <function name="GROUP" language="en_US">
75  <synopsis>
76  Gets or sets the channel group.
77  </synopsis>
78  <syntax>
79  <parameter name="category">
80  <para>Category name.</para>
81  </parameter>
82  </syntax>
83  <description>
84  <para><replaceable>category</replaceable> can be employed for more fine grained group management. Each channel
85  can only be member of exactly one group per <replaceable>category</replaceable>.</para>
86  </description>
87  </function>
88  <function name="GROUP_LIST" language="en_US">
89  <synopsis>
90  Gets a list of the groups set on a channel.
91  </synopsis>
92  <syntax />
93  <description>
94  <para>Gets a list of the groups set on a channel.</para>
95  </description>
96  </function>
97 
98  ***/
99 
100 static int group_count_function_read(struct ast_channel *chan, const char *cmd,
101  char *data, char *buf, size_t len)
102 {
103  int ret = -1;
104  int count = -1;
105  char group[80] = "", category[80] = "";
106 
107  if (!chan) {
108  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
109  return -1;
110  }
111 
112  ast_app_group_split_group(data, group, sizeof(group), category,
113  sizeof(category));
114 
115  /* If no group has been provided let's find one */
116  if (ast_strlen_zero(group)) {
117  struct ast_group_info *gi = NULL;
118 
120  for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
121  if (gi->chan != chan)
122  continue;
123  if (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))
124  break;
125  }
126  if (gi) {
127  ast_copy_string(group, gi->group, sizeof(group));
128  if (!ast_strlen_zero(gi->category))
129  ast_copy_string(category, gi->category, sizeof(category));
130  }
132  }
133 
134  if ((count = ast_app_group_get_count(group, category)) == -1) {
135  ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n", chan->name);
136  } else {
137  snprintf(buf, len, "%d", count);
138  ret = 0;
139  }
140 
141  return ret;
142 }
143 
145  .name = "GROUP_COUNT",
147  .read_max = 12,
148 };
149 
151  const char *cmd, char *data, char *buf,
152  size_t len)
153 {
154  int count;
155  char group[80] = "";
156  char category[80] = "";
157 
158  ast_app_group_split_group(data, group, sizeof(group), category,
159  sizeof(category));
160 
161  if (!ast_strlen_zero(group)) {
162  count = ast_app_group_match_get_count(group, category);
163  snprintf(buf, len, "%d", count);
164  return 0;
165  }
166 
167  return -1;
168 }
169 
171  .name = "GROUP_MATCH_COUNT",
173  .read_max = 12,
174  .write = NULL,
175 };
176 
177 static int group_function_read(struct ast_channel *chan, const char *cmd,
178  char *data, char *buf, size_t len)
179 {
180  int ret = -1;
181  struct ast_group_info *gi = NULL;
182 
183  if (!chan) {
184  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
185  return -1;
186  }
187 
189 
190  for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
191  if (gi->chan != chan)
192  continue;
193  if (ast_strlen_zero(data))
194  break;
195  if (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, data))
196  break;
197  }
198 
199  if (gi) {
200  ast_copy_string(buf, gi->group, len);
201  ret = 0;
202  }
203 
205 
206  return ret;
207 }
208 
209 static int group_function_write(struct ast_channel *chan, const char *cmd,
210  char *data, const char *value)
211 {
212  char grpcat[256];
213 
214  if (!chan) {
215  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
216  return -1;
217  }
218 
219  if (!value) {
220  return -1;
221  }
222 
223  if (!ast_strlen_zero(data)) {
224  snprintf(grpcat, sizeof(grpcat), "%s@%s", value, data);
225  } else {
226  ast_copy_string(grpcat, value, sizeof(grpcat));
227  }
228 
229  if (ast_app_group_set_channel(chan, grpcat))
231  "Setting a group requires an argument (group name)\n");
232 
233  return 0;
234 }
235 
237  .name = "GROUP",
238  .read = group_function_read,
239  .write = group_function_write,
240 };
241 
242 static int group_list_function_read(struct ast_channel *chan, const char *cmd,
243  char *data, char *buf, size_t len)
244 {
245  struct ast_group_info *gi = NULL;
246  char tmp1[1024] = "";
247  char tmp2[1024] = "";
248 
249  if (!chan)
250  return -1;
251 
253 
254  for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
255  if (gi->chan != chan)
256  continue;
257  if (!ast_strlen_zero(tmp1)) {
258  ast_copy_string(tmp2, tmp1, sizeof(tmp2));
259  if (!ast_strlen_zero(gi->category))
260  snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, gi->group, gi->category);
261  else
262  snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, gi->group);
263  } else {
264  if (!ast_strlen_zero(gi->category))
265  snprintf(tmp1, sizeof(tmp1), "%s@%s", gi->group, gi->category);
266  else
267  snprintf(tmp1, sizeof(tmp1), "%s", gi->group);
268  }
269  }
270 
272 
273  ast_copy_string(buf, tmp1, len);
274 
275  return 0;
276 }
277 
279  .name = "GROUP_LIST",
280  .read = group_list_function_read,
281  .write = NULL,
282 };
283 
284 static int unload_module(void)
285 {
286  int res = 0;
287 
288  res |= ast_custom_function_unregister(&group_count_function);
289  res |= ast_custom_function_unregister(&group_match_count_function);
290  res |= ast_custom_function_unregister(&group_list_function);
291  res |= ast_custom_function_unregister(&group_function);
292 
293  return res;
294 }
295 
296 static int load_module(void)
297 {
298  int res = 0;
299 
300  res |= ast_custom_function_register(&group_count_function);
301  res |= ast_custom_function_register(&group_match_count_function);
302  res |= ast_custom_function_register(&group_list_function);
303  res |= ast_custom_function_register(&group_function);
304 
305  return res;
306 }
307 
308 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel group dialplan functions");
Main Channel structure associated with a channel.
Definition: channel.h:742
channel group info
Definition: channel.h:2459
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
Asterisk main include file. File version handling, generic pbx functions.
int ast_app_group_set_channel(struct ast_channel *chan, const char *data)
Set the group for a channel, splitting the provided data into group and category, if specified...
Definition: app.c:1222
#define LOG_WARNING
Definition: logger.h:144
static struct ast_custom_function group_count_function
static struct ast_custom_function group_match_count_function
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
int value
Definition: syslog.c:39
static struct ast_custom_function group_function
static int group_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
Utility functions.
int ast_app_group_match_get_count(const char *groupmatch, const char *category)
Get the current channel count of all groups that match the specified pattern and category.
Definition: app.c:1289
int ast_app_group_split_group(const char *data, char *group, int group_max, char *category, int category_max)
Split a group string into group and category, returning a default category if none is provided...
Definition: app.c:1195
General Asterisk PBX channel definitions.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Data structure associated with a custom dialplan function.
Definition: pbx.h:95
static struct ast_custom_function group_list_function
static int group_function_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
static int group_match_count_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
char * group
Definition: channel.h:2462
Core PBX routines and definitions.
struct ast_channel * chan
Definition: channel.h:2460
struct ast_group_info * ast_app_group_list_head(void)
Get the head of the group count list.
Definition: app.c:1375
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int unload_module(void)
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int load_module(void)
char * category
Definition: channel.h:2461
int ast_app_group_list_unlock(void)
Unlock the group count list.
Definition: app.c:1380
static int group_list_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_group_info::@157 group_list
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
const char * name
Definition: pbx.h:96
int ast_app_group_get_count(const char *group, const char *category)
Get the current channel count of the specified group and category.
Definition: app.c:1269
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
static int group_count_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
int ast_app_group_list_rdlock(void)
Read Lock the group count list.
Definition: app.c:1370
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180