Merge more changes from svn/asterisk/team/russell/sla_updates

* Add support for private hold.  By setting "hold=private" for a trunk, only
  the station that put the call on hold will be able to retrieve it from hold.
  Also, by setting "hold=private" for a station, any call that station puts
  on hold can only be retrieved by that station.


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@57203 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Russell Bryant 18 years ago
parent 315c9614cb
commit 447561d7a2

@ -369,6 +369,15 @@ enum sla_trunk_state {
SLA_TRUNK_STATE_ONHOLD, SLA_TRUNK_STATE_ONHOLD,
}; };
enum sla_hold_access {
/*! This means that any station can put it on hold, and any station
* can retrieve the call from hold. */
SLA_HOLD_OPEN,
/*! This means that only the station that put the call on hold may
* retrieve it from hold. */
SLA_HOLD_PRIVATE,
};
struct sla_trunk_ref; struct sla_trunk_ref;
struct sla_station { struct sla_station {
@ -388,6 +397,9 @@ struct sla_station {
* is set for a specific trunk on this station, that will take * is set for a specific trunk on this station, that will take
* priority over this value. */ * priority over this value. */
unsigned int ring_delay; unsigned int ring_delay;
/*! This option uses the values in the sla_hold_access enum and sets the
* access control type for hold on this station. */
unsigned int hold_access:1;
}; };
struct sla_station_ref { struct sla_station_ref {
@ -414,6 +426,9 @@ struct sla_trunk {
/*! If set to 1, no station will be able to join an active call with /*! If set to 1, no station will be able to join an active call with
* this trunk. */ * this trunk. */
unsigned int barge_disabled:1; unsigned int barge_disabled:1;
/*! This option uses the values in the sla_hold_access enum and sets the
* access control type for hold on this trunk. */
unsigned int hold_access:1;
}; };
struct sla_trunk_ref { struct sla_trunk_ref {
@ -996,6 +1011,23 @@ static char meetme_usage[] =
"Usage: meetme (un)lock|(un)mute|kick|list [concise] <confno> <usernumber>\n" "Usage: meetme (un)lock|(un)mute|kick|list [concise] <confno> <usernumber>\n"
" Executes a command for the conference or on a conferee\n"; " Executes a command for the conference or on a conferee\n";
static const char *sla_hold_str(unsigned int hold_access)
{
const char *hold = "Unknown";
switch (hold_access) {
case SLA_HOLD_OPEN:
hold = "Open";
break;
case SLA_HOLD_PRIVATE:
hold = "Private";
default:
break;
}
return hold;
}
static int sla_show_trunks(int fd, int argc, char **argv) static int sla_show_trunks(int fd, int argc, char **argv)
{ {
const struct sla_trunk *trunk; const struct sla_trunk *trunk;
@ -1017,11 +1049,13 @@ static int sla_show_trunks(int fd, int argc, char **argv)
"=== ==> AutoContext: %s\n" "=== ==> AutoContext: %s\n"
"=== ==> RingTimeout: %s\n" "=== ==> RingTimeout: %s\n"
"=== ==> BargeAllowed: %s\n" "=== ==> BargeAllowed: %s\n"
"=== ==> HoldAccess: %s\n"
"=== ==> Stations ...\n", "=== ==> Stations ...\n",
trunk->name, trunk->device, trunk->name, trunk->device,
S_OR(trunk->autocontext, "(none)"), S_OR(trunk->autocontext, "(none)"),
ring_timeout, ring_timeout,
trunk->barge_disabled ? "No" : "Yes"); trunk->barge_disabled ? "No" : "Yes",
sla_hold_str(trunk->hold_access));
AST_RWLIST_RDLOCK(&sla_stations); AST_RWLIST_RDLOCK(&sla_stations);
AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry)
ast_cli(fd, "=== ==> Station name: %s\n", station_ref->station->name); ast_cli(fd, "=== ==> Station name: %s\n", station_ref->station->name);
@ -1081,10 +1115,12 @@ static int sla_show_stations(int fd, int argc, char **argv)
"=== ==> AutoContext: %s\n" "=== ==> AutoContext: %s\n"
"=== ==> RingTimeout: %s\n" "=== ==> RingTimeout: %s\n"
"=== ==> RingDelay: %s\n" "=== ==> RingDelay: %s\n"
"=== ==> HoldAccess: %s\n"
"=== ==> Trunks ...\n", "=== ==> Trunks ...\n",
station->name, station->device, station->name, station->device,
S_OR(station->autocontext, "(none)"), S_OR(station->autocontext, "(none)"),
ring_timeout, ring_delay); ring_timeout, ring_delay,
sla_hold_str(station->hold_access));
AST_RWLIST_RDLOCK(&sla_trunks); AST_RWLIST_RDLOCK(&sla_trunks);
AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) { AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
if (trunk_ref->ring_timeout) { if (trunk_ref->ring_timeout) {
@ -3070,12 +3106,32 @@ static struct sla_station *sla_find_station(const char *name)
return station; return station;
} }
static int sla_check_station_hold_access(const struct sla_trunk *trunk)
{
struct sla_station_ref *station_ref;
struct sla_trunk_ref *trunk_ref;
/* For each station that has this call on hold, check for private hold. */
AST_LIST_TRAVERSE(&trunk->stations, station_ref, entry) {
AST_LIST_TRAVERSE(&station_ref->station->trunks, trunk_ref, entry) {
if (trunk_ref->trunk != trunk)
continue;
if (trunk_ref->state == SLA_TRUNK_STATE_ONHOLD && trunk_ref->chan &&
station_ref->station->hold_access == SLA_HOLD_PRIVATE)
return 1;
return 0;
}
}
return 0;
}
/*! \brief Find a trunk reference on a station by name /*! \brief Find a trunk reference on a station by name
* \param station the station * \param station the station
* \param name the trunk's name * \param name the trunk's name
* \return a pointer to the station's trunk reference. If the trunk * \return a pointer to the station's trunk reference. If the trunk
* is not found, or if it is not idle and barge is disabled, * is not found, it is not idle and barge is disabled, or if
* then NULL will be returned. * it is on hold and private hold is set, then NULL will be returned.
*/ */
static struct sla_trunk_ref *sla_find_trunk_ref_byname(const struct sla_station *station, static struct sla_trunk_ref *sla_find_trunk_ref_byname(const struct sla_station *station,
const char *name) const char *name)
@ -3085,8 +3141,14 @@ static struct sla_trunk_ref *sla_find_trunk_ref_byname(const struct sla_station
AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) { AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
if (strcasecmp(trunk_ref->trunk->name, name)) if (strcasecmp(trunk_ref->trunk->name, name))
continue; continue;
if (trunk_ref->trunk->barge_disabled && trunk_ref->state != SLA_TRUNK_STATE_IDLE)
if ( (trunk_ref->trunk->barge_disabled
&& trunk_ref->state != SLA_TRUNK_STATE_IDLE) ||
(trunk_ref->trunk->hold_stations
&& trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE) ||
sla_check_station_hold_access(trunk_ref->trunk) )
trunk_ref = NULL; trunk_ref = NULL;
break; break;
} }
@ -4023,7 +4085,12 @@ static int sla_station_exec(struct ast_channel *chan, void *data)
AST_RWLIST_UNLOCK(&sla_trunks); AST_RWLIST_UNLOCK(&sla_trunks);
if (!trunk_ref) { if (!trunk_ref) {
if (ast_strlen_zero(trunk_name))
ast_log(LOG_NOTICE, "No trunks available for call.\n"); ast_log(LOG_NOTICE, "No trunks available for call.\n");
else {
ast_log(LOG_NOTICE, "Can't join existing call on trunk "
"'%s' due to access controls.\n", trunk_name);
}
pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION"); pbx_builtin_setvar_helper(chan, "SLASTATION_STATUS", "CONGESTION");
return 0; return 0;
} }
@ -4356,7 +4423,16 @@ static int sla_build_trunk(struct ast_config *cfg, const char *cat)
} }
} else if (!strcasecmp(var->name, "barge")) } else if (!strcasecmp(var->name, "barge"))
trunk->barge_disabled = ast_false(var->value); trunk->barge_disabled = ast_false(var->value);
else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) { else if (!strcasecmp(var->name, "hold")) {
if (!strcasecmp(var->value, "private"))
trunk->hold_access = SLA_HOLD_PRIVATE;
else if (!strcasecmp(var->value, "open"))
trunk->hold_access = SLA_HOLD_OPEN;
else {
ast_log(LOG_WARNING, "Invalid value '%s' for hold on trunk %s\n",
var->value, trunk->name);
}
} else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n", ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
var->name, var->lineno, SLA_CONFIG_FILE); var->name, var->lineno, SLA_CONFIG_FILE);
} }
@ -4482,6 +4558,16 @@ static int sla_build_station(struct ast_config *cfg, const char *cat)
var->value, station->name); var->value, station->name);
station->ring_delay = 0; station->ring_delay = 0;
} }
} else if (!strcasecmp(var->name, "hold")) {
if (!strcasecmp(var->value, "private"))
station->hold_access = SLA_HOLD_PRIVATE;
else if (!strcasecmp(var->value, "open"))
station->hold_access = SLA_HOLD_OPEN;
else {
ast_log(LOG_WARNING, "Invalid value '%s' for hold on station %s\n",
var->value, station->name);
}
} else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) { } else if (strcasecmp(var->name, "type") && strcasecmp(var->name, "device")) {
ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n", ast_log(LOG_ERROR, "Invalid option '%s' specified at line %d of %s!\n",
var->name, var->lineno, SLA_CONFIG_FILE); var->name, var->lineno, SLA_CONFIG_FILE);

@ -31,6 +31,14 @@
; allowed to join a call that is in progress. The default ; allowed to join a call that is in progress. The default
; value is "yes". ; value is "yes".
;hold=private ; This option configure hold permissions for this trunk.
; "open" - This means that any station can put this trunk
; on hold, and any station can retrieve it from
; hold. This is the default.
; "private" - This means that once a station puts the
; trunk on hold, no other station will be
; allowed to retrieve the call from hold.
;[line2] ;[line2]
;type=trunk ;type=trunk
;device=Zap/4 ;device=Zap/4
@ -63,6 +71,19 @@
;ringdelay=10 ; Set a time for how long to wait before beginning to ring this station ;ringdelay=10 ; Set a time for how long to wait before beginning to ring this station
; once there is an incoming call, in seconds. ; once there is an incoming call, in seconds.
;hold=private ; This option configure hold permissions for this station. Note
; that if private hold is set in the trunk entry, that will override
; anything here. However, if a trunk has open hold access, but this
; station is set to private hold, then the private hold will be in
; effect.
; "open" - This means that once this station puts a call
; on hold, any other station is allowed to retrieve
; it. This is the default.
; "private" - This means that once this station puts a
; call on hold, no other station will be
; allowed to retrieve the call from hold.
;trunk=line1 ; Individually list all of the trunks that will appear on this station. This ;trunk=line1 ; Individually list all of the trunks that will appear on this station. This
; order is significant. It should be the same order as they appear on the ; order is significant. It should be the same order as they appear on the
; phone. The order here defines the order of preference that the trunks will ; phone. The order here defines the order of preference that the trunks will

Loading…
Cancel
Save