--- Functionality changes from Asterisk 10 to Asterisk 11 --------------------
------------------------------------------------------------------------------
+ConfBridge
+-------------------
+ * Added menu action admin_toggle_mute_participants. This will mute / unmute
+ all non-admin participants on a conference. The confbridge configuration file
+ also allows for the default sounds played to all conference users when this
+ occurs to be overriden using sound_participants_unmuted and sound_participants_muted.
+ * Added menu action participant_count. This will playback the number of current
+ participants in a conference.
+
SIP Changes
-----------
* Asterisk will no longer substitute CID number for CID name into display
return S_OR(custom_sounds->join, "confbridge-join");
case CONF_SOUND_LEAVE:
return S_OR(custom_sounds->leave, "confbridge-leave");
+ case CONF_SOUND_PARTICIPANTS_MUTED:
+ return S_OR(custom_sounds->participantsmuted, "conf-now-muted");
+ case CONF_SOUND_PARTICIPANTS_UNMUTED:
+ return S_OR(custom_sounds->participantsunmuted, "conf-now-unmuted");
}
return "";
"");
}
+static int action_toggle_mute_participants(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user)
+{
+ struct conference_bridge_user *participant = NULL;
+ const char *sound_to_play;
+
+ ao2_lock(conference_bridge);
+
+ /* If already muted, then unmute */
+ conference_bridge->muted = conference_bridge->muted ? 0 : 1;
+ sound_to_play = conf_get_sound((conference_bridge->muted ? CONF_SOUND_PARTICIPANTS_MUTED : CONF_SOUND_PARTICIPANTS_UNMUTED),
+ conference_bridge_user->b_profile.sounds);
+
+ AST_LIST_TRAVERSE(&conference_bridge->users_list, participant, list) {
+ if (!ast_test_flag(&participant->u_profile, USER_OPT_ADMIN)) {
+ participant->features.mute = conference_bridge->muted;
+ }
+ }
+
+ ao2_unlock(conference_bridge);
+
+ /* The host needs to hear it seperately, as they don't get the audio from play_sound_helper */
+ ast_stream_and_wait(conference_bridge_user->chan, sound_to_play, "");
+
+ /* Announce to the group that all participants are muted */
+ ast_autoservice_start(conference_bridge_user->chan);
+ play_sound_helper(conference_bridge, sound_to_play, 0);
+ ast_autoservice_stop(conference_bridge_user->chan);
+
+ return 0;
+}
+
static int action_playback(struct ast_bridge_channel *bridge_channel, const char *playback_file)
{
char *file_copy = ast_strdupa(playback_file);
conference_bridge_user,
bridge_channel->chan);
break;
+ case MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS:
+ if (!isadmin) {
+ break;
+ }
+ action_toggle_mute_participants(conference_bridge, conference_bridge_user);
+ break;
+ case MENU_ACTION_PARTICIPANT_COUNT:
+ announce_user_count(conference_bridge, conference_bridge_user);
+ break;
case MENU_ACTION_PLAYBACK:
if (!stop_prompts) {
res |= action_playback(bridge_channel, menu_action->data.playback_file);
ast_cli(a->fd, "No conference bridge named '%s' found!\n", a->argv[2]);
return CLI_SUCCESS;
}
- ast_cli(a->fd, "Channel User Profile Bridge Profile Menu\n");
- ast_cli(a->fd, "============================= ================ ================ ================\n");
+ ast_cli(a->fd, "Channel User Profile Bridge Profile Menu CallerID\n");
+ ast_cli(a->fd, "============================= ================ ================ ================ ================\n");
ao2_lock(bridge);
AST_LIST_TRAVERSE(&bridge->users_list, participant, list) {
ast_cli(a->fd, "%-29s ", participant->chan->name);
ast_cli(a->fd, "%-17s", participant->u_profile.name);
ast_cli(a->fd, "%-17s", participant->b_profile.name);
ast_cli(a->fd, "%-17s", participant->menu_name);
+ ast_cli(a->fd, "%-17s", S_COR(participant->chan->caller.id.number.valid, participant->chan->caller.id.number.str, "<unknown>"));
ast_cli(a->fd, "\n");
}
ao2_unlock(bridge);
ast_string_field_set(sounds, join, sound_file);
} else if (!strcasecmp(sound_name, "sound_leave")) {
ast_string_field_set(sounds, leave, sound_file);
+ } else if (!strcasecmp(sound_name, "sound_participants_muted")) {
+ ast_string_field_set(sounds, participantsmuted, sound_file);
+ } else if (!strcasecmp(sound_name, "sound_participants_unmuted")) {
+ ast_string_field_set(sounds, participantsunmuted, sound_file);
} else {
return -1;
}
}
/* Using a bridge profile as a template is a little complicated due to the sounds. Since the sounds
* structure of a dynamic profile will need to be altered, a completely new sounds structure must be
- * create instead of simply holding a reference to the one built by the config file. */
+ * created instead of simply holding a reference to the one built by the config file. */
ast_string_field_set(sounds, onlyperson, tmp->sounds->onlyperson);
ast_string_field_set(sounds, hasjoin, tmp->sounds->hasjoin);
ast_string_field_set(sounds, hasleft, tmp->sounds->hasleft);
ast_string_field_set(sounds, unlockednow, tmp->sounds->unlockednow);
ast_string_field_set(sounds, lockednow, tmp->sounds->lockednow);
ast_string_field_set(sounds, errormenu, tmp->sounds->errormenu);
+ ast_string_field_set(sounds, participantsmuted, tmp->sounds->participantsmuted);
+ ast_string_field_set(sounds, participantsunmuted, tmp->sounds->participantsunmuted);
ao2_ref(tmp->sounds, -1); /* sounds struct copied over to it from the template by reference only. */
ao2_ref(oldsounds,-1); /* original sounds struct we don't need anymore */
case MENU_ACTION_RESET_LISTENING:
case MENU_ACTION_RESET_TALKING:
case MENU_ACTION_ADMIN_TOGGLE_LOCK:
+ case MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS:
+ case MENU_ACTION_PARTICIPANT_COUNT:
case MENU_ACTION_ADMIN_KICK_LAST:
case MENU_ACTION_LEAVE:
case MENU_ACTION_SET_SINGLE_VIDEO_SRC:
res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_DECREASE_TALKING, NULL);
} else if (!strcasecmp(action, "admin_toggle_conference_lock")) {
res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_ADMIN_TOGGLE_LOCK, NULL);
+ } else if (!strcasecmp(action, "admin_toggle_mute_participants")) {
+ res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS, NULL);
+ } else if (!strcasecmp(action, "participant_count")) {
+ res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_PARTICIPANT_COUNT, NULL);
} else if (!strcasecmp(action, "admin_kick_last")) {
res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_ADMIN_KICK_LAST, NULL);
} else if (!strcasecmp(action, "leave_conference")) {
ast_cli(a->fd,"sound_unlocked_now: %s\n", conf_get_sound(CONF_SOUND_UNLOCKED_NOW, b_profile.sounds));
ast_cli(a->fd,"sound_lockednow: %s\n", conf_get_sound(CONF_SOUND_LOCKED_NOW, b_profile.sounds));
ast_cli(a->fd,"sound_error_menu: %s\n", conf_get_sound(CONF_SOUND_ERROR_MENU, b_profile.sounds));
+ ast_cli(a->fd,"sound_participants_muted: %s\n", conf_get_sound(CONF_SOUND_PARTICIPANTS_MUTED, b_profile.sounds));
+ ast_cli(a->fd,"sound_participants_unmuted: %s\n", conf_get_sound(CONF_SOUND_PARTICIPANTS_UNMUTED, b_profile.sounds));
ast_cli(a->fd,"\n");
conf_bridge_profile_destroy(&b_profile);
case MENU_ACTION_ADMIN_TOGGLE_LOCK:
ast_cli(a->fd, "admin_toggle_conference_lock");
break;
+ case MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS:
+ ast_cli(a->fd, "admin_toggle_mute_participants");
+ break;
+ case MENU_ACTION_PARTICIPANT_COUNT:
+ ast_cli(a->fd, "participant_count");
+ break;
case MENU_ACTION_ADMIN_KICK_LAST:
ast_cli(a->fd, "admin_kick_last");
break;
conf_bridge_profile_copy(result, &b_data->b_profile);
return result;
}
+ } else {
+ ast_channel_unlock(chan);
}
- ast_channel_unlock(chan);
}
if (ast_strlen_zero(bridge_profile_name)) {
bridge_profile_name = DEFAULT_BRIDGE_PROFILE;
MENU_ACTION_NOOP,
MENU_ACTION_SET_SINGLE_VIDEO_SRC,
MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC,
+ MENU_ACTION_PARTICIPANT_COUNT,
+ MENU_ACTION_ADMIN_TOGGLE_MUTE_PARTICIPANTS,
};
/*! The conference menu action contains both
CONF_SOUND_ERROR_MENU,
CONF_SOUND_JOIN,
CONF_SOUND_LEAVE,
+ CONF_SOUND_PARTICIPANTS_MUTED,
+ CONF_SOUND_PARTICIPANTS_UNMUTED,
};
struct bridge_profile_sounds {
AST_STRING_FIELD(errormenu);
AST_STRING_FIELD(leave);
AST_STRING_FIELD(join);
+ AST_STRING_FIELD(participantsmuted);
+ AST_STRING_FIELD(participantsunmuted);
);
};
unsigned int users; /*!< Number of users present */
unsigned int markedusers; /*!< Number of marked users present */
unsigned int locked:1; /*!< Is this conference bridge locked? */
+ unsigned int muted:1; /*!< Is this conference bridge muted? */
struct ast_channel *playback_chan; /*!< Channel used for playback into the conference bridge */
struct ast_channel *record_chan; /*!< Channel used for recording the conference */
pthread_t record_thread; /*!< The thread the recording chan lives in */
; to whatever operation the video_mode option is set to
; upon release of the video src.
+; admin_toggle_mute_participants ; This action allows an administrator to toggle the mute
+ ; state for all non-admins within a conference. All
+ ; admin users are unaffected by this option. Note that all
+ ; users, regardless of their admin status, are notified
+ ; that the conference is muted.
+
+; participant_count ; This action plays back the number of participants currently
+ ; in a conference
+
[sample_user_menu]
type=menu
*=playback_and_continue(conf-usermenu)
--- /dev/null
+#
+# Table structure for table `sipfriends`
+#
+
+CREATE TABLE IF NOT EXISTS `sipfriends` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(10) NOT NULL,
+ `ipaddr` varchar(15) DEFAULT NULL,
+ `port` int(5) DEFAULT NULL,
+ `regseconds` int(11) DEFAULT NULL,
+ `defaultuser` varchar(10) DEFAULT NULL,
+ `fullcontact` varchar(35) DEFAULT NULL,
+ `regserver` varchar(20) DEFAULT NULL,
+ `useragent` varchar(20) DEFAULT NULL,
+ `lastms` int(11) DEFAULT NULL,
+ `host` varchar(40) DEFAULT NULL,
+ `type` enum('friend','user','peer') DEFAULT NULL,
+ `context` varchar(40) DEFAULT NULL,
+ `permit` varchar(40) DEFAULT NULL,
+ `deny` varchar(40) DEFAULT NULL,
+ `secret` varchar(40) DEFAULT NULL,
+ `md5secret` varchar(40) DEFAULT NULL,
+ `remotesecret` varchar(40) DEFAULT NULL,
+ `transport` enum('udp','tcp','udp,tcp','tcp,udp') DEFAULT NULL,
+ `dtmfmode` enum('rfc2833','info','shortinfo','inband','auto') DEFAULT NULL,
+ `directmedia` enum('yes','no','nonat','update') DEFAULT NULL,
+ `nat` enum('yes','no','never','route') DEFAULT NULL,
+ `callgroup` varchar(40) DEFAULT NULL,
+ `pickupgroup` varchar(40) DEFAULT NULL,
+ `language` varchar(40) DEFAULT NULL,
+ `allow` varchar(200) DEFAULT NULL,
+ `insecure` varchar(40) DEFAULT NULL,
+ `trustrpid` enum('yes','no') DEFAULT NULL,
+ `progressinband` enum('yes','no','never') DEFAULT NULL,
+ `promiscredir` enum('yes','no') DEFAULT NULL,
+ `useclientcode` enum('yes','no') DEFAULT NULL,
+ `accountcode` varchar(40) DEFAULT NULL,
+ `setvar` varchar(40) DEFAULT NULL,
+ `callerid` varchar(40) DEFAULT NULL,
+ `amaflags` varchar(40) DEFAULT NULL,
+ `callcounter` enum('yes','no') DEFAULT NULL,
+ `busylevel` int(11) DEFAULT NULL,
+ `allowoverlap` enum('yes','no') DEFAULT NULL,
+ `allowsubscribe` enum('yes','no') DEFAULT NULL,
+ `videosupport` enum('yes','no') DEFAULT NULL,
+ `maxcallbitrate` int(11) DEFAULT NULL,
+ `rfc2833compensate` enum('yes','no') DEFAULT NULL,
+ `mailbox` varchar(40) DEFAULT NULL,
+ `session-timers` enum('accept','refuse','originate') DEFAULT NULL,
+ `session-expires` int(11) DEFAULT NULL,
+ `session-minse` int(11) DEFAULT NULL,
+ `session-refresher` enum('uac','uas') DEFAULT NULL,
+ `t38pt_usertpsource` varchar(40) DEFAULT NULL,
+ `regexten` varchar(40) DEFAULT NULL,
+ `fromdomain` varchar(40) DEFAULT NULL,
+ `fromuser` varchar(40) DEFAULT NULL,
+ `qualify` varchar(40) DEFAULT NULL,
+ `defaultip` varchar(40) DEFAULT NULL,
+ `rtptimeout` int(11) DEFAULT NULL,
+ `rtpholdtimeout` int(11) DEFAULT NULL,
+ `sendrpid` enum('yes','no') DEFAULT NULL,
+ `outboundproxy` varchar(40) DEFAULT NULL,
+ `callbackextension` varchar(40) DEFAULT NULL,
+ `registertrying` enum('yes','no') DEFAULT NULL,
+ `timert1` int(11) DEFAULT NULL,
+ `timerb` int(11) DEFAULT NULL,
+ `qualifyfreq` int(11) DEFAULT NULL,
+ `constantssrc` enum('yes','no') DEFAULT NULL,
+ `contactpermit` varchar(40) DEFAULT NULL,
+ `contactdeny` varchar(40) DEFAULT NULL,
+ `usereqphone` enum('yes','no') DEFAULT NULL,
+ `textsupport` enum('yes','no') DEFAULT NULL,
+ `faxdetect` enum('yes','no') DEFAULT NULL,
+ `buggymwi` enum('yes','no') DEFAULT NULL,
+ `auth` varchar(40) DEFAULT NULL,
+ `fullname` varchar(40) DEFAULT NULL,
+ `trunkname` varchar(40) DEFAULT NULL,
+ `cid_number` varchar(40) DEFAULT NULL,
+ `callingpres` enum('allowed_not_screened','allowed_passed_screen','allowed_failed_screen','allowed','prohib_not_screened','prohib_passed_screen','prohib_failed_screen','prohib') DEFAULT NULL,
+ `mohinterpret` varchar(40) DEFAULT NULL,
+ `mohsuggest` varchar(40) DEFAULT NULL,
+ `parkinglot` varchar(40) DEFAULT NULL,
+ `hasvoicemail` enum('yes','no') DEFAULT NULL,
+ `subscribemwi` enum('yes','no') DEFAULT NULL,
+ `vmexten` varchar(40) DEFAULT NULL,
+ `autoframing` enum('yes','no') DEFAULT NULL,
+ `rtpkeepalive` int(11) DEFAULT NULL,
+ `call-limit` int(11) DEFAULT NULL,
+ `g726nonstandard` enum('yes','no') DEFAULT NULL,
+ `ignoresdpversion` enum('yes','no') DEFAULT NULL,
+ `allowtransfer` enum('yes','no') DEFAULT NULL,
+ `dynamic` enum('yes','no') DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `name` (`name`),
+ KEY `ipaddr` (`ipaddr`,`port`),
+ KEY `host` (`host`,`port`)
+) ENGINE=MyISAM;