summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfred E. Heggestad <alfred.heggestad@gmail.com>2017-12-09 14:21:33 +0100
committerAlfred E. Heggestad <alfred.heggestad@gmail.com>2017-12-09 14:21:33 +0100
commit1110ecaeee1be1a7d13f12d193086bbddf9a7f4a (patch)
tree6af6c4a9b4710a6e08580e4601c1fb63dd90f248
parent9d8ce318ba0207059e705da7589b61fe699d515c (diff)
ua: add UA_EVENT_CALL_RTCP event
this event is called for every received RTCP report. mqtt: add JSON encoding of RTCP stats
-rw-r--r--include/baresip.h11
-rw-r--r--modules/mqtt/publish.c69
-rw-r--r--src/core.h2
-rw-r--r--src/stream.c8
-rw-r--r--src/ua.c1
5 files changed, 88 insertions, 3 deletions
diff --git a/include/baresip.h b/include/baresip.h
index e6ff968..a04d88f 100644
--- a/include/baresip.h
+++ b/include/baresip.h
@@ -26,6 +26,7 @@ struct sa;
struct sdp_media;
struct sdp_session;
struct sip_msg;
+struct stream;
struct ua;
struct vidframe;
struct vidrect;
@@ -586,6 +587,7 @@ enum ua_event {
UA_EVENT_CALL_TRANSFER_FAILED,
UA_EVENT_CALL_DTMF_START,
UA_EVENT_CALL_DTMF_END,
+ UA_EVENT_CALL_RTCP,
UA_EVENT_MAX,
};
@@ -983,6 +985,7 @@ int audio_set_player(struct audio *au, const char *mod, const char *device);
void audio_encoder_cycle(struct audio *audio);
int audio_level_get(const struct audio *au, double *level);
int audio_debug(struct re_printf *pf, const struct audio *a);
+struct stream *audio_strm(const struct audio *a);
/*
@@ -1002,6 +1005,14 @@ void video_encoder_cycle(struct video *video);
int video_debug(struct re_printf *pf, const struct video *v);
uint32_t video_calc_rtp_timestamp(int64_t pts, unsigned fps);
double video_calc_seconds(uint32_t rtp_ts);
+struct stream *video_strm(const struct video *v);
+
+
+/*
+ * Generic stream
+ */
+
+const struct rtcp_stats *stream_rtcp_stats(const struct stream *strm);
/*
diff --git a/modules/mqtt/publish.c b/modules/mqtt/publish.c
index 068400a..dd250c2 100644
--- a/modules/mqtt/publish.c
+++ b/modules/mqtt/publish.c
@@ -16,8 +16,54 @@
*/
+static int add_rtcp_stats(struct odict *od_parent, const struct rtcp_stats *rs)
+{
+ struct odict *od = NULL, *tx = NULL, *rx = NULL;
+ int err = 0;
+
+ if (!od_parent || !rs)
+ return EINVAL;
+
+ err = odict_alloc(&od, 8);
+ err |= odict_alloc(&tx, 8);
+ err |= odict_alloc(&rx, 8);
+ if (err)
+ goto out;
+
+ err = odict_entry_add(tx, "sent", ODICT_INT, (int64_t)rs->tx.sent);
+ err |= odict_entry_add(tx, "lost", ODICT_INT, (int64_t)rs->tx.lost);
+ err |= odict_entry_add(tx, "jit", ODICT_INT, (int64_t)rs->tx.jit);
+ if (err)
+ goto out;
+
+ err = odict_entry_add(rx, "sent", ODICT_INT, (int64_t)rs->rx.sent);
+ err |= odict_entry_add(rx, "lost", ODICT_INT, (int64_t)rs->rx.lost);
+ err |= odict_entry_add(rx, "jit", ODICT_INT, (int64_t)rs->rx.jit);
+ if (err)
+ goto out;
+
+ err = odict_entry_add(od, "tx", ODICT_OBJECT, tx);
+ err |= odict_entry_add(od, "rx", ODICT_OBJECT, rx);
+ err |= odict_entry_add(od, "rtt", ODICT_INT, (int64_t)rs->rtt);
+ if (err)
+ goto out;
+
+ /* add object to the parent */
+ err = odict_entry_add(od_parent, "rtcp_stats", ODICT_OBJECT, od);
+ if (err)
+ goto out;
+
+ out:
+ mem_deref(od);
+
+ return err;
+}
+
+
/*
* Relay UA events as publish messages to the Broker
+ *
+ * XXX: move JSON encoding to baresip core
*/
static void ua_event_handler(struct ua *ua, enum ua_event ev,
struct call *call, const char *prm, void *arg)
@@ -42,9 +88,30 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev,
dir = call_is_outgoing(call) ? "outgoing" : "incoming";
- err |= odict_entry_add(od, "direction", ODICT_STRING, dir );
+ err |= odict_entry_add(od, "direction", ODICT_STRING, dir);
err |= odict_entry_add(od, "peeruri",
ODICT_STRING, call_peeruri(call));
+ if (err)
+ goto out;
+ }
+
+ if (str_isset(prm)) {
+ err = odict_entry_add(od, "param", ODICT_STRING, prm);
+ if (err)
+ goto out;
+ }
+
+ if (ev == UA_EVENT_CALL_RTCP) {
+ struct stream *strm = NULL;
+
+ if (0 == str_casecmp(prm, "audio"))
+ strm = audio_strm(call_audio(call));
+ else if (0 == str_casecmp(prm, "video"))
+ strm = video_strm(call_video(call));
+
+ err = add_rtcp_stats(od, stream_rtcp_stats(strm));
+ if (err)
+ goto out;
}
err = mqtt_publish_message(mqtt, "/baresip/event", "%H",
diff --git a/src/core.h b/src/core.h
index 91c4a65..a390e0c 100644
--- a/src/core.h
+++ b/src/core.h
@@ -133,7 +133,6 @@ int audio_encoder_set(struct audio *a, const struct aucodec *ac,
int pt_tx, const char *params);
int audio_decoder_set(struct audio *a, const struct aucodec *ac,
int pt_rx, const char *params);
-struct stream *audio_strm(const struct audio *a);
int audio_send_digit(struct audio *a, char key);
void audio_sdp_attr_decode(struct audio *a);
int audio_print_rtpstat(struct re_printf *pf, const struct audio *au);
@@ -471,7 +470,6 @@ int video_encoder_set(struct video *v, struct vidcodec *vc,
int pt_tx, const char *params);
int video_decoder_set(struct video *v, struct vidcodec *vc, int pt_rx,
const char *fmtp);
-struct stream *video_strm(const struct video *v);
void video_update_picture(struct video *v);
void video_sdp_attr_decode(struct video *v);
int video_print(struct re_printf *pf, const struct video *v);
diff --git a/src/stream.c b/src/stream.c
index d3d0bba..641502f 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -289,6 +289,8 @@ static void rtcp_handler(const struct sa *src, struct rtcp_msg *msg, void *arg)
if (s->cfg.rtp_stats)
call_set_xrtpstat(s->call);
+ ua_event(call_get_ua(s->call), UA_EVENT_CALL_RTCP, s->call,
+ "%s", sdp_media_name(stream_sdpmedia(s)));
break;
}
}
@@ -717,3 +719,9 @@ int stream_print(struct re_printf *pf, const struct stream *s)
s->metric_tx.cur_bitrate,
s->metric_rx.cur_bitrate);
}
+
+
+const struct rtcp_stats *stream_rtcp_stats(const struct stream *strm)
+{
+ return strm ? &strm->rtcp_stats : NULL;
+}
diff --git a/src/ua.c b/src/ua.c
index e6a019d..b736bf3 100644
--- a/src/ua.c
+++ b/src/ua.c
@@ -1657,6 +1657,7 @@ const char *uag_event_str(enum ua_event ev)
case UA_EVENT_CALL_TRANSFER_FAILED: return "TRANSFER_FAILED";
case UA_EVENT_CALL_DTMF_START: return "CALL_DTMF_START";
case UA_EVENT_CALL_DTMF_END: return "CALL_DTMF_END";
+ case UA_EVENT_CALL_RTCP: return "CALL_RTCP";
default: return "?";
}
}