]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
app_confbridge: Add function to retrieve channels.
authorNaveen Albert <asterisk@phreaknet.org>
Fri, 29 Apr 2022 16:42:55 +0000 (16:42 +0000)
committerGeorge Joseph <gjoseph@digium.com>
Fri, 13 May 2022 14:55:29 +0000 (09:55 -0500)
Adds the CONFBRIDGE_CHANNELS function which can be used
to retrieve a comma-separated list of channels, filtered
by a particular type of participant category. This output
can then be used with functions like UNSHIFT, SHIFT, POP,
etc.

ASTERISK-30036 #close

Change-Id: I1950aff932437476dc1abab6f47fb4ac90520b83

apps/app_confbridge.c
doc/CHANGES-staging/app_confbridge_channels.txt [new file with mode: 0644]

index d365075560d8246fb620f51fdf719f57376929ad..ae17bcab6fab59a18a50c65d09c74d729709089c 100644 (file)
                        <ref type="application">ConfKick</ref>
                        <ref type="function">CONFBRIDGE</ref>
                        <ref type="function">CONFBRIDGE_INFO</ref>
+                       <ref type="function">CONFBRIDGE_CHANNELS</ref>
                </see-also>
        </application>
        <application name="ConfKick" language="en_US">
                        <ref type="application">ConfBridge</ref>
                        <ref type="function">CONFBRIDGE</ref>
                        <ref type="function">CONFBRIDGE_INFO</ref>
+                       <ref type="function">CONFBRIDGE_CHANNELS</ref>
                </see-also>
        </application>
        <function name="CONFBRIDGE" language="en_US">
                        <para>This function returns a non-negative integer for valid conference
                        names and an empty string for invalid conference names.</para>
                </description>
+               <see-also>
+                       <ref type="function">CONFBRIDGE_CHANNELS</ref>
+               </see-also>
+       </function>
+       <function name="CONFBRIDGE_CHANNELS" language="en_US">
+               <since>
+                       <version>16.26.0</version>
+                       <version>18.12.0</version>
+                       <version>19.4.0</version>
+               </since>
+               <synopsis>
+                       Get a list of channels in a ConfBridge conference.
+               </synopsis>
+               <syntax>
+                       <parameter name="type" required="true">
+                               <para>What conference information is requested.</para>
+                               <enumlist>
+                                       <enum name="admins">
+                                               <para>Get the number of admin users in the conference.</para>
+                                       </enum>
+                                       <enum name="marked">
+                                               <para>Get the number of marked users in the conference.</para>
+                                       </enum>
+                                       <enum name="parties">
+                                               <para>Get the number of total users in the conference.</para>
+                                       </enum>
+                                       <enum name="active">
+                                               <para>Get the number of active users in the conference.</para>
+                                       </enum>
+                                       <enum name="waiting">
+                                               <para>Get the number of waiting users in the conference.</para>
+                                       </enum>
+                               </enumlist>
+                       </parameter>
+                       <parameter name="conf" required="true">
+                               <para>The name of the conference being referenced.</para>
+                       </parameter>
+               </syntax>
+               <description>
+                       <para>This function returns a comma-separated list of channels in a ConfBridge conference, optionally filtered by a type of participant.</para>
+               </description>
+               <see-also>
+                       <ref type="function">CONFBRIDGE_INFO</ref>
+               </see-also>
        </function>
        <manager name="ConfbridgeList" language="en_US">
                <synopsis>
@@ -3829,6 +3875,90 @@ static struct ast_custom_function confbridge_info_function = {
        .read = func_confbridge_info,
 };
 
+static int func_confbridge_channels(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+       char *parse, *outbuf;
+       struct confbridge_conference *conference;
+       struct confbridge_user *user;
+       int bytes, count = 0;
+       size_t outlen;
+       AST_DECLARE_APP_ARGS(args,
+               AST_APP_ARG(type);
+               AST_APP_ARG(confno);
+       );
+
+       /* parse all the required arguments and make sure they exist. */
+       if (ast_strlen_zero(data)) {
+               return -1;
+       }
+       parse = ast_strdupa(data);
+       AST_STANDARD_APP_ARGS(args, parse);
+       if (ast_strlen_zero(args.confno) || ast_strlen_zero(args.type)) {
+               ast_log(LOG_WARNING, "Usage: %s(category,confno)", cmd);
+               return -1;
+       }
+       conference = ao2_find(conference_bridges, args.confno, OBJ_KEY);
+       if (!conference) {
+               ast_debug(1, "No such conference: %s\n", args.confno);
+               return -1;
+       }
+
+       outbuf = buf;
+       outlen = len;
+
+       ao2_lock(conference);
+       if (!strcasecmp(args.type, "parties")) {
+               AST_LIST_TRAVERSE(&conference->active_list, user, list) {
+                       bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
+                       outbuf += bytes;
+                       outlen -= bytes;
+               }
+               AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
+                       bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
+                       outbuf += bytes;
+                       outlen -= bytes;
+               }
+       } else if (!strcasecmp(args.type, "active")) {
+               AST_LIST_TRAVERSE(&conference->active_list, user, list) {
+                       bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
+                       outbuf += bytes;
+                       outlen -= bytes;
+               }
+       } else if (!strcasecmp(args.type, "waiting")) {
+               AST_LIST_TRAVERSE(&conference->waiting_list, user, list) {
+                       bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
+                       outbuf += bytes;
+                       outlen -= bytes;
+               }
+       } else if (!strcasecmp(args.type, "admins")) {
+               AST_LIST_TRAVERSE(&conference->active_list, user, list) {
+                       if (ast_test_flag(&user->u_profile, USER_OPT_ADMIN)) {
+                               bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
+                               outbuf += bytes;
+                               outlen -= bytes;
+                       }
+               }
+       } else if (!strcasecmp(args.type, "marked")) {
+               AST_LIST_TRAVERSE(&conference->active_list, user, list) {
+                       if (ast_test_flag(&user->u_profile, USER_OPT_MARKEDUSER)) {
+                               bytes = snprintf(outbuf, outlen, "%s%s", count++ ? "," : "", ast_channel_name(user->chan));
+                               outbuf += bytes;
+                               outlen -= bytes;
+                       }
+               }
+       } else {
+               ast_log(LOG_ERROR, "Invalid keyword '%s' passed to %s.\n", args.type, cmd);
+       }
+       ao2_unlock(conference);
+       ao2_ref(conference, -1);
+       return 0;
+}
+
+static struct ast_custom_function confbridge_channels_function = {
+       .name = "CONFBRIDGE_CHANNELS",
+       .read = func_confbridge_channels,
+};
+
 static int action_confbridgelist_item(struct mansession *s, const char *id_text, struct confbridge_conference *conference, struct confbridge_user *user, int waiting)
 {
        struct ast_channel_snapshot *snapshot;
@@ -4406,6 +4536,7 @@ static int unload_module(void)
 
        ast_custom_function_unregister(&confbridge_function);
        ast_custom_function_unregister(&confbridge_info_function);
+       ast_custom_function_unregister(&confbridge_channels_function);
 
        ast_cli_unregister_multiple(cli_confbridge, ARRAY_LEN(cli_confbridge));
 
@@ -4477,6 +4608,7 @@ static int load_module(void)
 
        res |= ast_custom_function_register_escalating(&confbridge_function, AST_CFE_WRITE);
        res |= ast_custom_function_register(&confbridge_info_function);
+       res |= ast_custom_function_register(&confbridge_channels_function);
 
        res |= ast_cli_register_multiple(cli_confbridge, ARRAY_LEN(cli_confbridge));
 
diff --git a/doc/CHANGES-staging/app_confbridge_channels.txt b/doc/CHANGES-staging/app_confbridge_channels.txt
new file mode 100644 (file)
index 0000000..485f664
--- /dev/null
@@ -0,0 +1,7 @@
+Subject: app_confbridge
+
+Adds the CONFBRIDGE_CHANNELS function which can
+be used to retrieve a list of channels in a ConfBridge,
+optionally filtered by a particular category. This
+list can then be used with functions like SHIFT, POP,
+UNSHIFT, etc.