/*! 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;
+ /*! Whether this trunk is currently on hold, meaning that once a station
+ * connects to it, the trunk channel needs to have UNHOLD indicated to it. */
+ unsigned int on_hold:1;
};
struct sla_trunk_ref {
continue;
if ( (trunk_ref->trunk->barge_disabled
- && trunk_ref->state != SLA_TRUNK_STATE_IDLE) ||
+ && trunk_ref->state == SLA_TRUNK_STATE_UP) ||
(trunk_ref->trunk->hold_stations
&& trunk_ref->trunk->hold_access == SLA_HOLD_PRIVATE
&& trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) ||
- sla_check_station_hold_access(trunk_ref->trunk, station) )
+ sla_check_station_hold_access(trunk_ref->trunk, station) )
+ {
trunk_ref = NULL;
+ }
break;
}
}
trunk_ref->chan = NULL;
if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations) &&
- !trunk_ref->trunk->hold_stations) {
+ trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
strncat(conf_name, "|K", sizeof(conf_name) - strlen(conf_name) - 1);
admin_exec(NULL, conf_name);
+ trunk_ref->trunk->hold_stations = 0;
sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
}
event->station->name, event->trunk_ref->trunk->name);
sla_change_trunk_state(event->trunk_ref->trunk, SLA_TRUNK_STATE_ONHOLD,
INACTIVE_TRUNK_REFS, event->trunk_ref);
-
+
+ if (event->trunk_ref->trunk->active_stations == 1) {
+ /* The station putting it on hold is the only one on the call, so start
+ * Music on hold to the trunk. */
+ event->trunk_ref->trunk->on_hold = 1;
+ ast_indicate(event->trunk_ref->trunk->chan, AST_CONTROL_HOLD);
+ }
+
ast_softhangup(event->trunk_ref->chan, AST_CAUSE_NORMAL);
event->trunk_ref->chan = NULL;
}
sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
trunk_ref->trunk->chan = NULL;
+ trunk_ref->trunk->on_hold = 0;
ast_dial_join(dial);
ast_dial_destroy(dial);
}
}
- ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1);
+ if (ast_atomic_fetchadd_int((int *) &trunk_ref->trunk->active_stations, 1) == 0 &&
+ trunk_ref->trunk->on_hold) {
+ trunk_ref->trunk->on_hold = 0;
+ ast_indicate(trunk_ref->trunk->chan, AST_CONTROL_UNHOLD);
+ }
+
snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk_ref->trunk->name);
ast_set_flag(&conf_flags,
CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_STATION);
}
trunk_ref->chan = NULL;
if (ast_atomic_dec_and_test((int *) &trunk_ref->trunk->active_stations) &&
- !trunk_ref->trunk->hold_stations) {
+ trunk_ref->state != SLA_TRUNK_STATE_ONHOLD_BYME) {
strncat(conf_name, "|K", sizeof(conf_name) - strlen(conf_name) - 1);
admin_exec(NULL, conf_name);
+ trunk_ref->trunk->hold_stations = 0;
sla_change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_IDLE, ALL_TRUNK_REFS, NULL);
}
dispose_conf(conf);
conf = NULL;
trunk->chan = NULL;
+ trunk->on_hold = 0;
pbx_builtin_setvar_helper(chan, "SLATRUNK_STATUS", "SUCCESS");