From: Naveen Albert Date: Fri, 29 Apr 2022 16:42:55 +0000 (+0000) Subject: app_confbridge: Add function to retrieve channels. X-Git-Tag: 18.13.0-rc1~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b0de0675653f4e0fd28e0ad9d8929aeee16a58e6;p=thirdparty%2Fasterisk.git app_confbridge: Add function to retrieve channels. 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 --- diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index d365075560..ae17bcab6f 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -128,6 +128,7 @@ ConfKick CONFBRIDGE CONFBRIDGE_INFO + CONFBRIDGE_CHANNELS @@ -164,6 +165,7 @@ ConfBridge CONFBRIDGE CONFBRIDGE_INFO + CONFBRIDGE_CHANNELS @@ -248,6 +250,50 @@ This function returns a non-negative integer for valid conference names and an empty string for invalid conference names. + + CONFBRIDGE_CHANNELS + + + + + 16.26.0 + 18.12.0 + 19.4.0 + + + Get a list of channels in a ConfBridge conference. + + + + What conference information is requested. + + + Get the number of admin users in the conference. + + + Get the number of marked users in the conference. + + + Get the number of total users in the conference. + + + Get the number of active users in the conference. + + + Get the number of waiting users in the conference. + + + + + The name of the conference being referenced. + + + + This function returns a comma-separated list of channels in a ConfBridge conference, optionally filtered by a type of participant. + + + CONFBRIDGE_INFO + @@ -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 index 0000000000..485f664268 --- /dev/null +++ b/doc/CHANGES-staging/app_confbridge_channels.txt @@ -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.