[asterisk-commits] russell: branch russell/sla_rewrite r53293 -
/team/russell/sla_rewrite/apps/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Tue Feb 6 16:54:51 MST 2007
Author: russell
Date: Tue Feb 6 17:54:50 2007
New Revision: 53293
URL: http://svn.digium.com/view/asterisk?view=rev&rev=53293
Log:
Add hold support to SLA. This is not tested very heavily due to some problems
on my system right now ...
Modified:
team/russell/sla_rewrite/apps/app_meetme.c
Modified: team/russell/sla_rewrite/apps/app_meetme.c
URL: http://svn.digium.com/view/asterisk/team/russell/sla_rewrite/apps/app_meetme.c?view=diff&rev=53293&r1=53292&r2=53293
==============================================================================
--- team/russell/sla_rewrite/apps/app_meetme.c (original)
+++ team/russell/sla_rewrite/apps/app_meetme.c Tue Feb 6 17:54:50 2007
@@ -152,6 +152,8 @@
CONFFLAG_STARTMUTED = (1 << 24),
/*! Pass DTMF through the conference */
CONFFLAG_PASS_DTMF = (1 << 25),
+ CONFFLAG_SLA_STATION = (1 << 26),
+ CONFFLAG_SLA_TRUNK = (1 << 27),
};
enum {
@@ -344,6 +346,7 @@
SLA_TRUNK_STATE_IDLE,
SLA_TRUNK_STATE_RINGING,
SLA_TRUNK_STATE_UP,
+ SLA_TRUNK_STATE_ONHOLD,
};
struct sla_trunk_ref;
@@ -377,6 +380,8 @@
unsigned int num_stations;
/*! Number of stations currently on a call with this trunk */
unsigned int active_stations;
+ /*! Number of stations that have this trunk on hold. */
+ unsigned int hold_stations;
struct ast_channel *chan;
pthread_t station_thread;
};
@@ -392,11 +397,24 @@
static const char sla_registrar[] = "SLA";
+enum sla_event_type {
+ SLA_EVENT_HOLD,
+ SLA_EVENT_UNHOLD
+};
+
+struct sla_event {
+ enum sla_event_type type;
+ struct sla_station *station;
+ struct sla_trunk_ref *trunk_ref;
+ AST_LIST_ENTRY(sla_event) entry;
+};
+
static struct sla {
pthread_t thread;
ast_cond_t cond;
ast_mutex_t lock;
AST_LIST_HEAD_NOLOCK(, sla_trunk_ref) ringing_trunks;
+ AST_LIST_HEAD_NOLOCK(, sla_event) event_q;
unsigned int stop:1;
} sla = {
.thread = AST_PTHREADT_NULL,
@@ -933,6 +951,7 @@
S(SLA_TRUNK_STATE_IDLE)
S(SLA_TRUNK_STATE_RINGING)
S(SLA_TRUNK_STATE_UP)
+ S(SLA_TRUNK_STATE_ONHOLD)
}
return "Uknown State";
#undef S
@@ -1069,6 +1088,47 @@
return;
AST_LIST_INSERT_TAIL(&user->frame_q, f, frame_list);
}
+}
+
+static void sla_queue_event(enum sla_event_type type, const struct ast_channel *chan,
+ struct ast_conference *conf)
+{
+ struct sla_event *event;
+ struct sla_station *station;
+ struct sla_trunk_ref *trunk_ref;
+ char *trunk_name;
+
+ AST_RWLIST_RDLOCK(&sla_stations);
+ AST_RWLIST_TRAVERSE(&sla_stations, station, entry) {
+ if (station->chan != chan)
+ continue;
+ trunk_name = ast_strdupa(conf->confno);
+ strsep(&trunk_name, "_");
+ if (ast_strlen_zero(trunk_name)) {
+ AST_RWLIST_UNLOCK(&sla_stations);
+ ast_log(LOG_ERROR, "Invalid conference name for SLA - '%s'!\n", conf->confno);
+ return;
+ }
+ AST_LIST_TRAVERSE(&station->trunks, trunk_ref, entry) {
+ if (!strcmp(trunk_ref->trunk->name, trunk_name))
+ break;
+ }
+ }
+ AST_RWLIST_UNLOCK(&sla_stations);
+
+ if (!trunk_ref) {
+ ast_log(LOG_DEBUG, "Trunk not found for event!\n");
+ return;
+ }
+
+ if (!(event = ast_calloc(1, sizeof(*event))))
+ return;
+
+ event->type = type;
+ event->trunk_ref = trunk_ref;
+ event->station = station;
+
+ AST_LIST_INSERT_TAIL(&sla.event_q, event, entry);
}
static int conf_run(struct ast_channel *chan, struct ast_conference *conf, int confflags, char *optargs[])
@@ -1842,6 +1902,24 @@
} else if ((f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END)
&& confflags & CONFFLAG_PASS_DTMF) {
conf_queue_dtmf(conf, user, f);
+ } else if ((confflags & CONFFLAG_SLA_STATION) && f->frametype == AST_FRAME_CONTROL) {
+ switch (f->subclass) {
+ case AST_CONTROL_HOLD:
+ ast_log(LOG_DEBUG, "Got a HOLD frame!\n");
+ ast_mutex_lock(&sla.lock);
+ sla_queue_event(SLA_EVENT_HOLD, chan, conf);
+ ast_cond_signal(&sla.cond);
+ ast_mutex_unlock(&sla.lock);
+ break;
+ case AST_CONTROL_UNHOLD:
+ ast_log(LOG_DEBUG, "Got a UNHOLD frame!\n");
+ ast_mutex_lock(&sla.lock);
+ sla_queue_event(SLA_EVENT_UNHOLD, chan, conf);
+ ast_cond_signal(&sla.cond);
+ ast_mutex_unlock(&sla.lock);
+ default:
+ break;
+ }
} else if (option_debug) {
ast_log(LOG_DEBUG,
"Got unrecognized frame on channel %s, f->frametype=%d,f->subclass=%d\n",
@@ -2915,7 +2993,8 @@
ast_atomic_fetchadd_int((int *) &trunk->active_stations, 1);
snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk->name);
- ast_set_flag(&conf_flags, CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF);
+ ast_set_flag(&conf_flags,
+ CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_PASS_DTMF | CONFFLAG_SLA_STATION);
ast_answer(station->chan);
conf = build_conf(conf_name, "", "", 0, 0, 1);
if (conf)
@@ -2937,14 +3016,40 @@
for (; !sla.stop;) {
struct sla_trunk_ref *trunk_ref;
struct sla_station_ref *station_ref;
+ struct sla_event *event;
enum ast_dial_result dial_res = AST_DIAL_RESULT_TRYING;
ast_mutex_lock(&sla.lock);
- if (AST_LIST_EMPTY(&sla.ringing_trunks)) {
+ if (AST_LIST_EMPTY(&sla.ringing_trunks) && AST_LIST_EMPTY(&sla.event_q)) {
ast_cond_wait(&sla.cond, &sla.lock);
if (sla.stop)
break;
ast_log(LOG_DEBUG, "Ooh, I was woken up!\n");
+ }
+
+ while ((event = AST_LIST_REMOVE_HEAD(&sla.event_q, entry))) {
+ switch (event->type) {
+ case SLA_EVENT_HOLD:
+ ast_log(LOG_DEBUG, "HOLD, station: %s trunk: %s\n",
+ event->station->name, event->trunk_ref->trunk->name);
+ ast_atomic_fetchadd_int((int *) &event->trunk_ref->trunk->hold_stations, 1);
+ trunk_ref->state = SLA_TRUNK_STATE_ONHOLD;
+ ast_device_state_changed("SLA:%s_%s",
+ event->station->name, event->trunk_ref->trunk->name);
+ break;
+ case SLA_EVENT_UNHOLD:
+ ast_log(LOG_DEBUG, "UNHOLD, station: %s trunk: %s\n",
+ event->station->name, event->trunk_ref->trunk->name);
+ if (ast_atomic_dec_and_test((int *) &event->trunk_ref->trunk->hold_stations) == 1)
+ change_trunk_state(trunk_ref->trunk, SLA_TRUNK_STATE_UP);
+ else {
+ trunk_ref->state = SLA_TRUNK_STATE_UP;
+ ast_device_state_changed("SLA:%s_%s",
+ event->station->name, event->trunk_ref->trunk->name);
+ }
+ break;
+ }
+ free(event);
}
/* At this point, we know there are ringing trunks. So, make sure that every
@@ -2992,6 +3097,7 @@
pthread_t dont_care;
ast_mutex_t cond_lock;
ast_cond_t cond;
+ unsigned int done = 0;
switch ((dial_res = ast_dial_status(station_ref->station->dial))) {
case AST_DIAL_RESULT_HANGUP:
@@ -3055,6 +3161,12 @@
}
if (dial_res == AST_DIAL_RESULT_ANSWERED)
break;
+ ast_mutex_lock(&sla.lock);
+ if (!AST_LIST_EMPTY(&sla.event_q))
+ done = 1;
+ ast_mutex_unlock(&sla.lock);
+ if (done)
+ break;
}
AST_LIST_TRAVERSE_SAFE_END
if (dial_res != AST_DIAL_RESULT_ANSWERED)
@@ -3163,7 +3275,8 @@
snprintf(conf_name, sizeof(conf_name), "SLA_%s", trunk->name);
ast_set_flag(&conf_flags,
- CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER | CONFFLAG_PASS_DTMF);
+ CONFFLAG_QUIET | CONFFLAG_MARKEDEXIT | CONFFLAG_MARKEDUSER |
+ CONFFLAG_PASS_DTMF | CONFFLAG_SLA_TRUNK);
conf = build_conf(conf_name, "", "", 1, 1, 1);
ast_mutex_lock(args->cond_lock);
@@ -3392,6 +3505,9 @@
case SLA_TRUNK_STATE_UP:
res = AST_DEVICE_INUSE;
break;
+ case SLA_TRUNK_STATE_ONHOLD:
+ res = AST_DEVICE_ONHOLD;
+ break;
}
AST_RWLIST_UNLOCK(&sla_trunks);
}
More information about the asterisk-commits
mailing list