mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-07 18:38:02 +00:00
Merged revisions 57203 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r57203 | russell | 2007-02-28 16:07:05 -0600 (Wed, 28 Feb 2007) | 7 lines 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/trunk@57204 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -363,6 +363,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 {
|
||||||
@@ -382,6 +391,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 {
|
||||||
@@ -408,6 +420,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 {
|
||||||
@@ -993,6 +1008,23 @@ static const 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;
|
||||||
@@ -1014,11 +1046,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);
|
||||||
@@ -1075,13 +1109,15 @@ static int sla_show_stations(int fd, int argc, char **argv)
|
|||||||
ast_cli(fd, "=== ---------------------------------------------------------\n"
|
ast_cli(fd, "=== ---------------------------------------------------------\n"
|
||||||
"=== Station Name: %s\n"
|
"=== Station Name: %s\n"
|
||||||
"=== ==> Device: %s\n"
|
"=== ==> Device: %s\n"
|
||||||
"=== ==> AutoContext: %s\n"
|
"=== ==> AutoContext: %s\n"
|
||||||
"=== ==> RingTimeout: %s\n"
|
"=== ==> RingTimeout: %s\n"
|
||||||
"=== ==> RingDelay: %s\n"
|
"=== ==> RingDelay: %s\n"
|
||||||
"=== ==> Trunks ...\n",
|
"=== ==> HoldAccess: %s\n"
|
||||||
station->name, station->device,
|
"=== ==> Trunks ...\n",
|
||||||
S_OR(station->autocontext, "(none)"),
|
station->name, station->device,
|
||||||
ring_timeout, ring_delay);
|
S_OR(station->autocontext, "(none)"),
|
||||||
|
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) {
|
||||||
@@ -3080,12 +3116,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)
|
||||||
@@ -3095,8 +3151,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4033,7 +4095,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) {
|
||||||
ast_log(LOG_NOTICE, "No trunks available for call.\n");
|
if (ast_strlen_zero(trunk_name))
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@@ -4366,7 +4433,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);
|
||||||
}
|
}
|
||||||
@@ -4492,6 +4568,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);
|
||||||
|
|||||||
@@ -13,23 +13,31 @@
|
|||||||
|
|
||||||
; ---- Trunk Declarations -------------
|
; ---- Trunk Declarations -------------
|
||||||
;
|
;
|
||||||
;[line1] ; Provide a name for this trunk.
|
;[line1] ; Provide a name for this trunk.
|
||||||
;type=trunk ; This line is what marks this entry as a trunk.
|
;type=trunk ; This line is what marks this entry as a trunk.
|
||||||
;
|
;
|
||||||
;device=Zap/3 ; Map this trunk declaration to a specific device.
|
;device=Zap/3 ; Map this trunk declaration to a specific device.
|
||||||
; NOTE: At this point, this *must* be a zap channel!
|
; NOTE: At this point, this *must* be a zap channel!
|
||||||
|
|
||||||
;autocontext=line1 ; This supports automatic generation of the dialplan entries
|
;autocontext=line1 ; This supports automatic generation of the dialplan entries
|
||||||
; if the autocontext option is used. Each trunk should have
|
; if the autocontext option is used. Each trunk should have
|
||||||
; a unique context name. Then, in zapata.conf, this device
|
; a unique context name. Then, in zapata.conf, this device
|
||||||
; should be configured to have incoming calls go to this context.
|
; should be configured to have incoming calls go to this context.
|
||||||
|
|
||||||
;ringtimeout=30 ; Set how long to allow this trunk to ring on an inbound call before hanging
|
;ringtimeout=30 ; Set how long to allow this trunk to ring on an inbound call before hanging
|
||||||
; it up as an unanswered call. The value is in seconds.
|
; it up as an unanswered call. The value is in seconds.
|
||||||
|
|
||||||
;barge=no ; If this option is set to "no", then no station will be
|
;barge=no ; If this option is set to "no", then no station will be
|
||||||
; 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
|
||||||
@@ -50,37 +58,50 @@
|
|||||||
|
|
||||||
; ---- Station Declarations ------------
|
; ---- Station Declarations ------------
|
||||||
|
|
||||||
;type=station ; This line indicates that this entry is a station.
|
;type=station ; This line indicates that this entry is a station.
|
||||||
|
|
||||||
;autocontext=sla_stations ; This supports automatic generation of the dialplan entries if
|
;autocontext=sla_stations ; This supports automatic generation of the dialplan entries if
|
||||||
; the autocontext option is used. All stations can use the same
|
; the autocontext option is used. All stations can use the same
|
||||||
; context without conflict. The device for this station should
|
; context without conflict. The device for this station should
|
||||||
; have its context configured to the same one listed here.
|
; have its context configured to the same one listed here.
|
||||||
|
|
||||||
;ringtimeout=10 ; Set a timeout for how long to allow the station to ring for an
|
;ringtimeout=10 ; Set a timeout for how long to allow the station to ring for an
|
||||||
; incoming call, in seconds.
|
; incoming call, in seconds.
|
||||||
|
|
||||||
;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.
|
||||||
|
|
||||||
;trunk=line1 ; Individually list all of the trunks that will appear on this station. This
|
;hold=private ; This option configure hold permissions for this station. Note
|
||||||
; order is significant. It should be the same order as they appear on the
|
; that if private hold is set in the trunk entry, that will override
|
||||||
; phone. The order here defines the order of preference that the trunks will
|
; anything here. However, if a trunk has open hold access, but this
|
||||||
; be used.
|
; 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
|
||||||
|
; 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
|
||||||
|
; be used.
|
||||||
;trunk=line2
|
;trunk=line2
|
||||||
;trunk=line3,ringdelay=5 ; A ring delay for the station can also be specified for a specific trunk.
|
;trunk=line3,ringdelay=5 ; A ring delay for the station can also be specified for a specific trunk.
|
||||||
; If a ring delay is specified both for the whole station and for a specific
|
; If a ring delay is specified both for the whole station and for a specific
|
||||||
; trunk on a station, the setting for the specific trunk will take priority.
|
; trunk on a station, the setting for the specific trunk will take priority.
|
||||||
; This value is in seconds.
|
; This value is in seconds.
|
||||||
|
|
||||||
;trunk=line4,ringtimeout=5 ; A ring timeout for the station can also be specified for a specific trunk.
|
;trunk=line4,ringtimeout=5 ; A ring timeout for the station can also be specified for a specific trunk.
|
||||||
; If a ring timeout is specified both for the whole station and for a specific
|
; If a ring timeout is specified both for the whole station and for a specific
|
||||||
; trunk on a station, the setting for the specific trunk will take priority.
|
; trunk on a station, the setting for the specific trunk will take priority.
|
||||||
; This value is in seconds.
|
; This value is in seconds.
|
||||||
|
|
||||||
|
|
||||||
;[station1](station) ; Define a station that uses the configuration from the template "station".
|
;[station1](station) ; Define a station that uses the configuration from the template "station".
|
||||||
;device=SIP/station1 ; Each station must be mapped to a device.
|
;device=SIP/station1 ; Each station must be mapped to a device.
|
||||||
;
|
;
|
||||||
;[station2](station)
|
;[station2](station)
|
||||||
;device=SIP/station2
|
;device=SIP/station2
|
||||||
|
|||||||
Reference in New Issue
Block a user