diff -ur asterisk-13.7.0-rc2/apps/app_confbridge.c asterisk-13.7.0-rc2-jm/apps/app_confbridge.c --- asterisk-13.7.0-rc2/apps/app_confbridge.c 2015-12-18 11:18:42.000000000 -0700 +++ asterisk-13.7.0-rc2-jm/apps/app_confbridge.c 2016-01-11 16:50:46.063000000 -0700 @@ -325,6 +325,8 @@ static const char app[] = "ConfBridge"; +#define STR_CONCISE "concise" + /*! Number of buckets our conference bridges container can have */ #define CONFERENCE_BRIDGE_BUCKETS 53 @@ -1487,6 +1489,7 @@ const struct confbridge_user *user = hook_pvt; RAII_VAR(struct confbridge_conference *, conference, NULL, ao2_cleanup); struct ast_json *talking_extras; + struct confbridge_user *cur_user = NULL; conference = ao2_find(conference_bridges, user->conference->name, OBJ_KEY); if (!conference) { @@ -1502,6 +1505,11 @@ } send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0); + AST_LIST_TRAVERSE(&conference->active_list, cur_user, list) { + if (!strcasecmp(ast_channel_name(cur_user->chan), ast_channel_name(bridge_channel->chan))) { + cur_user->user_is_talking = talking; + } + } ast_json_unref(talking_extras); return 0; } @@ -1919,7 +1927,7 @@ conference->muted = mute; AST_LIST_TRAVERSE(&conference->active_list, cur_user, list) { - if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) { + if (!ast_test_flag(&cur_user->u_profile, USER_OPT_ADMIN)) { /* Set user level to bridge level mute request. */ cur_user->muted = mute; conf_update_user_mute(cur_user); @@ -2380,7 +2388,7 @@ return CLI_SUCCESS; } -static void handle_cli_confbridge_list_item(struct ast_cli_args *a, struct confbridge_user *user, int waiting) +static void handle_cli_confbridge_list_item(struct ast_cli_args *a, struct confbridge_user *user, int waiting, int concise) { char flag_str[6 + 1];/* Max flags + terminator */ int pos = 0; @@ -2398,6 +2406,9 @@ if (ast_test_flag(&user->u_profile, USER_OPT_ENDMARKED)) { flag_str[pos++] = 'E'; } + if (ast_test_flag(&user->u_profile, USER_OPT_TALKER_DETECT)) { + flag_str[pos++] = 'T'; + } if (user->muted) { flag_str[pos++] = 'm'; } @@ -2406,14 +2417,37 @@ } flag_str[pos] = '\0'; - ast_cli(a->fd, "%-30s %-6s %-16s %-16s %-16s %s\n", - ast_channel_name(user->chan), - flag_str, - user->u_profile.name, - user->b_profile.name, - user->menu_name, - S_COR(ast_channel_caller(user->chan)->id.number.valid, - ast_channel_caller(user->chan)->id.number.str, "")); +/* meetme reports */ +/* ast_cli(a->fd, "%d!%s!%s!%s!%s!%s!%s!%s!%d!%02d:%02d:%02d\n", */ +/* + * voip-vm-tmp*CLI> meetme list 4078 concise + * 1!914696472264!NTT AMERICA COM!SIP/v00.dllstx09.us.bb.gin.ntt.net-1-0000021a!!!!!1!00:31:15 + * 2!917039442479!WASHINGTON VA!SIP/v00.dllstx09.us.bb.gin.ntt.net-1-00000221!!!!!0!00:20:05 + * userno!cidnum!cidname!channel!admin!monitor!muted!talkrequest!talking!time + */ + + + if (concise) { + ast_cli(a->fd, "%s!%s!%s!%d!%s\n", + ast_channel_name(user->chan), + S_COR(ast_channel_caller(user->chan)->id.number.valid, + ast_channel_caller(user->chan)->id.number.str, "unknown"), + S_COR(ast_channel_caller(user->chan)->id.name.valid, + ast_channel_caller(user->chan)->id.name.str, ""), + user->user_is_talking, flag_str); + } else { + ast_cli(a->fd, "%-30s %-6s %-16s %-16s %-16s %8d %-8s %-16s\n", + ast_channel_name(user->chan), + flag_str, + user->u_profile.name, + user->b_profile.name, + user->menu_name, + user->user_is_talking, + S_COR(ast_channel_caller(user->chan)->id.number.valid, + ast_channel_caller(user->chan)->id.number.str, ""), + S_COR(ast_channel_caller(user->chan)->id.name.valid, + ast_channel_caller(user->chan)->id.name.str, "")); + } } static char *handle_cli_confbridge_list(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) @@ -2424,7 +2458,7 @@ case CLI_INIT: e->command = "confbridge list"; e->usage = - "Usage: confbridge list []\n" + "Usage: confbridge list [] [concise]\n" " Lists all currently active conference bridges or a specific conference bridge.\n" "\n" " When a conference bridge name is provided, flags may be shown for users. Below\n" @@ -2436,6 +2470,7 @@ " W - The user must wait for a marked user to join\n" " E - The user will be kicked after the last marked user leaves the conference\n" " m - The user is muted\n" + " T - The user has talking detection enabled\n" " w - The user is waiting for a marked user to join\n"; return NULL; case CLI_GENERATE: @@ -2445,36 +2480,47 @@ return NULL; } - if (a->argc == 2) { + if (a->argc == 2 || (a->argc == 3 && !strcasecmp(a->argv[2], STR_CONCISE))) { struct ao2_iterator iter; + int concise = (a->argc == 3); - ast_cli(a->fd, "Conference Bridge Name Users Marked Locked?\n"); - ast_cli(a->fd, "================================ ====== ====== ========\n"); + if (!concise) { + ast_cli(a->fd, "Conference Bridge Name Users Marked Locked?\n"); + ast_cli(a->fd, "================================ ====== ====== ========\n"); + } iter = ao2_iterator_init(conference_bridges, 0); while ((conference = ao2_iterator_next(&iter))) { - ast_cli(a->fd, "%-32s %6u %6u %s\n", conference->name, conference->activeusers + conference->waitingusers, conference->markedusers, (conference->locked ? "locked" : "unlocked")); + if (concise) { + ast_cli(a->fd, "%s!%u!%u!%u\n", conference->name, conference->activeusers + conference->waitingusers, conference->markedusers, conference->locked); + } else { + ast_cli(a->fd, "%-32s %6u %6u %s\n", conference->name, conference->activeusers + conference->waitingusers, conference->markedusers, (conference->locked ? "locked" : "unlocked")); + } ao2_ref(conference, -1); } ao2_iterator_destroy(&iter); return CLI_SUCCESS; } - if (a->argc == 3) { + if (a->argc == 3|| (a->argc == 4 && !strcasecmp(a->argv[3], STR_CONCISE))) { struct confbridge_user *user; + int concise = (a->argc == 4); conference = ao2_find(conference_bridges, a->argv[2], OBJ_KEY); if (!conference) { ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]); return CLI_SUCCESS; } - ast_cli(a->fd, "Channel Flags User Profile Bridge Profile Menu CallerID\n"); - ast_cli(a->fd, "============================== ====== ================ ================ ================ ================\n"); + if (!concise) + { + ast_cli(a->fd, "Channel Flags User Profile Bridge Profile Menu Talking CallerID\n"); + ast_cli(a->fd, "============================== ====== ================ ================ ================ ======= ================\n"); + } ao2_lock(conference); AST_LIST_TRAVERSE(&conference->active_list, user, list) { - handle_cli_confbridge_list_item(a, user, 0); + handle_cli_confbridge_list_item(a, user, 0, concise); } AST_LIST_TRAVERSE(&conference->waiting_list, user, list) { - handle_cli_confbridge_list_item(a, user, 1); + handle_cli_confbridge_list_item(a, user, 1, concise); } ao2_unlock(conference); ao2_ref(conference, -1); @@ -2847,6 +2893,7 @@ "EndMarked: %s\r\n" "Waiting: %s\r\n" "Muted: %s\r\n" + "Talking: %s\r\n" "AnsweredTime: %d\r\n" "\r\n", id_text, @@ -2860,6 +2907,7 @@ ast_test_flag(&user->u_profile, USER_OPT_ENDMARKED) ? "Yes" : "No", waiting ? "Yes" : "No", user->muted ? "Yes" : "No", + user->user_is_talking ? "Yes" : "No", ast_channel_get_up_time(user->chan)); } diff -ur asterisk-13.7.0-rc2/apps/confbridge/include/confbridge.h asterisk-13.7.0-rc2-jm/apps/confbridge/include/confbridge.h --- asterisk-13.7.0-rc2/apps/confbridge/include/confbridge.h 2015-12-18 11:18:42.000000000 -0700 +++ asterisk-13.7.0-rc2-jm/apps/confbridge/include/confbridge.h 2016-01-11 16:46:38.214000000 -0700 @@ -250,6 +250,7 @@ unsigned int muted:1; /*!< Has the user requested to be muted? */ unsigned int kicked:1; /*!< User has been kicked from the conference */ unsigned int playing_moh:1; /*!< MOH is currently being played to the user */ + unsigned int user_is_talking:1; /*!< Is the user currently talking */ AST_LIST_HEAD_NOLOCK(, post_join_action) post_join_list; /*!< List of sounds to play after joining */; AST_LIST_ENTRY(confbridge_user) list; /*!< Linked list information */ };