summaryrefslogtreecommitdiff
path: root/channels/chan_gulp.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2013-06-22 12:40:16 +0000
committerJoshua Colp <jcolp@digium.com>2013-06-22 12:40:16 +0000
commit94ec267888e907862cab6c5e24163ca3a9a72070 (patch)
tree7fd73b66642e77ca85e09c397775cab1b62e11e8 /channels/chan_gulp.c
parent1267c91315f6850483022b4535beadbc0069b22e (diff)
Migrate PeerStatus events to stasis, add stasis endpoints, and add chan_pjsip device state.
(closes issue ASTERISK-21489) (closes issue ASTERISK-21503) Review: https://reviewboard.asterisk.org/r/2601/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@392538 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_gulp.c')
-rw-r--r--channels/chan_gulp.c78
1 files changed, 74 insertions, 4 deletions
diff --git a/channels/chan_gulp.c b/channels/chan_gulp.c
index 967349e0b..9e939a0f4 100644
--- a/channels/chan_gulp.c
+++ b/channels/chan_gulp.c
@@ -53,6 +53,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/musiconhold.h"
#include "asterisk/causes.h"
#include "asterisk/taskprocessor.h"
+#include "asterisk/stasis_endpoints.h"
+#include "asterisk/stasis_channels.h"
#include "asterisk/res_sip.h"
#include "asterisk/res_sip_session.h"
@@ -82,6 +84,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static const char desc[] = "Gulp SIP Channel";
static const char channel_type[] = "Gulp";
+static unsigned int chan_idx;
+
/*!
* \brief Positions of various media
*/
@@ -125,6 +129,7 @@ static struct ast_frame *gulp_read(struct ast_channel *ast);
static int gulp_write(struct ast_channel *ast, struct ast_frame *f);
static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
static int gulp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
+static int gulp_devicestate(const char *data);
/*! \brief PBX interface structure for channel registration */
static struct ast_channel_tech gulp_tech = {
@@ -143,6 +148,7 @@ static struct ast_channel_tech gulp_tech = {
.exception = gulp_read,
.indicate = gulp_indicate,
.fixup = gulp_fixup,
+ .devicestate = gulp_devicestate,
.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER
};
@@ -422,8 +428,8 @@ static struct ast_channel *gulp_new(struct ast_sip_session *session, int state,
return NULL;
}
- if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", linkedid, 0, "Gulp/%s-%.*s", ast_sorcery_object_get_id(session->endpoint),
- (int)session->inv_session->dlg->call_id->id.slen, session->inv_session->dlg->call_id->id.ptr))) {
+ if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", linkedid, 0, "Gulp/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
+ ast_atomic_fetchadd_int((int *)&chan_idx, +1)))) {
ao2_cleanup(pvt);
return NULL;
}
@@ -461,6 +467,8 @@ static struct ast_channel *gulp_new(struct ast_sip_session *session, int state,
ast_channel_exten_set(chan, S_OR(exten, "s"));
ast_channel_priority_set(chan, 1);
+ ast_endpoint_add_channel(session->endpoint->persistent, chan);
+
return chan;
}
@@ -623,6 +631,68 @@ static int gulp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
return 0;
}
+/*! \brief Function called to get the device state of an endpoint */
+static int gulp_devicestate(const char *data)
+{
+ RAII_VAR(struct ast_sip_endpoint *, endpoint, ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", data), ao2_cleanup);
+ enum ast_device_state state = AST_DEVICE_UNKNOWN;
+ RAII_VAR(struct ast_endpoint_snapshot *, endpoint_snapshot, NULL, ao2_cleanup);
+ RAII_VAR(struct stasis_caching_topic *, caching_topic, NULL, ao2_cleanup);
+ struct ast_devstate_aggregate aggregate;
+ int num, inuse = 0;
+
+ if (!endpoint) {
+ return AST_DEVICE_INVALID;
+ }
+
+ endpoint_snapshot = ast_endpoint_latest_snapshot(ast_endpoint_get_tech(endpoint->persistent),
+ ast_endpoint_get_resource(endpoint->persistent), 1);
+
+ if (endpoint_snapshot->state == AST_ENDPOINT_OFFLINE) {
+ state = AST_DEVICE_UNAVAILABLE;
+ } else if (endpoint_snapshot->state == AST_ENDPOINT_ONLINE) {
+ state = AST_DEVICE_NOT_INUSE;
+ }
+
+ if (!endpoint_snapshot->num_channels || !(caching_topic = ast_channel_topic_all_cached())) {
+ return state;
+ }
+
+ ast_devstate_aggregate_init(&aggregate);
+
+ ao2_ref(caching_topic, +1);
+
+ for (num = 0; num < endpoint_snapshot->num_channels; num++) {
+ RAII_VAR(struct stasis_message *, msg, stasis_cache_get_extended(caching_topic, ast_channel_snapshot_type(),
+ endpoint_snapshot->channel_ids[num], 1), ao2_cleanup);
+ struct ast_channel_snapshot *snapshot;
+
+ if (!msg) {
+ continue;
+ }
+
+ snapshot = stasis_message_data(msg);
+
+ if (snapshot->state == AST_STATE_DOWN) {
+ ast_devstate_aggregate_add(&aggregate, AST_DEVICE_NOT_INUSE);
+ } else if (snapshot->state == AST_STATE_RINGING) {
+ ast_devstate_aggregate_add(&aggregate, AST_DEVICE_RINGING);
+ } else if ((snapshot->state == AST_STATE_UP) || (snapshot->state == AST_STATE_RING) ||
+ (snapshot->state == AST_STATE_BUSY)) {
+ ast_devstate_aggregate_add(&aggregate, AST_DEVICE_INUSE);
+ inuse++;
+ }
+ }
+
+ if (endpoint->devicestate_busy_at && (inuse == endpoint->devicestate_busy_at)) {
+ state = AST_DEVICE_BUSY;
+ } else if (ast_devstate_aggregate_result(&aggregate) != AST_DEVICE_INVALID) {
+ state = ast_devstate_aggregate_result(&aggregate);
+ }
+
+ return state;
+}
+
struct indicate_data {
struct ast_sip_session *session;
int condition;
@@ -731,6 +801,7 @@ static int gulp_indicate(struct ast_channel *ast, int condition, const void *dat
} else {
res = -1;
}
+ ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Gulp/%s", ast_sorcery_object_get_id(session->endpoint));
break;
case AST_CONTROL_BUSY:
if (ast_channel_state(ast) != AST_STATE_UP) {
@@ -1326,7 +1397,7 @@ static int gulp_incoming_request(struct ast_sip_session *session, struct pjsip_r
return 0;
}
- if (!(session->channel = gulp_new(session, AST_STATE_DOWN, session->exten, NULL, NULL, NULL))) {
+ if (!(session->channel = gulp_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL))) {
if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS) {
ast_sip_session_send_response(session, packet);
}
@@ -1335,7 +1406,6 @@ static int gulp_incoming_request(struct ast_sip_session *session, struct pjsip_r
return -1;
}
- ast_setstate(session->channel, AST_STATE_RING);
res = ast_pbx_start(session->channel);
switch (res) {