diff options
author | Matthew Jordan <mjordan@digium.com> | 2014-07-31 11:57:51 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2014-07-31 11:57:51 +0000 |
commit | bbeaeea1a3f5591ca4f2342e8a014ccf1e8bd8d9 (patch) | |
tree | 6303e34248dded3c50cd7d4c676eeb5820d1dd9e /channels | |
parent | 922e3203a9303acbc95a334793a41e07e3f4772d (diff) |
res_hep_rtcp: Add module that sends RTCP information to a Homer Server
This patch adds a new module to Asterisk, res_hep_rtcp. The module subscribes
to the RTCP topics in Stasis and receives RTCP information back from the
message bus. It encodes into HEPv3 packets and sends the information to the
res_hep module for transmission.
Using this, someone with a Homer server can get live call quality monitoring
for all RTP-based channels in their Asterisk 12+ systems.
In addition, there were a few bugs in the RTP engine, res_rtp_asterisk, and
chan_pjsip that were uncovered by the tests written for the Asterisk Test
Suite. This patch fixes the following:
1) chan_pjsip failed to set its channel unique ids on its RTP instance on
outbound calls. It now does this in the appropriate location, in the
serialized call callback.
2) The rtp_engine was overflowing some values when packed into JSON.
Specifically, some longs and unsigned ints can't be be packed into integer
values, for obvious reasons. Since libjansson only supports integers,
floats, strings, booleans, and objects, we print these values into strings.
3) res_rtp_asterisk had a few problems:
(a) it would emit a source IP address of 0.0.0.0 if bound to that IP
address. We now use ast_find_ourip to get a better IP address, and
properly marshal the result into an ast_strdupa'd string.
(b) Reports can be generated with no report bodies. In particular, this
occurs when a sender is transmitting information to a receiver (who
will send no RTP back to the sender). As such, the sender has no report
body for what it received. We now properly handle this case, and the
sender will emit SR reports with no body. Likewise, if we receive an
RTCP packet with no report body, we will still generate the appropriate
events.
ASTERISK-24119 #close
........
Merged revisions 419823 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419825 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_pjsip.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 92a96eb0e..c958f8086 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -353,6 +353,16 @@ static struct ast_rtp_glue chan_pjsip_rtp_glue = { .update_peer = chan_pjsip_set_rtp_peer, }; +static void set_channel_on_rtp_instance(struct chan_pjsip_pvt *pvt, const char *channel_id) +{ + if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) { + ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, channel_id); + } + if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) { + ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, channel_id); + } +} + /*! \brief Function called to create a new PJSIP Asterisk channel */ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name) { @@ -452,12 +462,7 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s * these will need to be recaptured as well */ pvt->media[SIP_MEDIA_AUDIO] = ao2_find(session->media, "audio", OBJ_KEY); pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY); - if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) { - ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ast_channel_uniqueid(chan)); - } - if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) { - ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(chan)); - } + set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(chan)); return chan; } @@ -685,12 +690,7 @@ static int fixup(void *data) struct chan_pjsip_pvt *pvt = channel->pvt; channel->session->channel = fix_data->chan; - if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) { - ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ast_channel_uniqueid(fix_data->chan)); - } - if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) { - ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(fix_data->chan)); - } + set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(fix_data->chan)); return 0; } @@ -1523,7 +1523,9 @@ static void update_initial_connected_line(struct ast_sip_session *session) static int call(void *data) { - struct ast_sip_session *session = data; + struct ast_sip_channel_pvt *channel = data; + struct ast_sip_session *session = channel->session; + struct chan_pjsip_pvt *pvt = channel->pvt; pjsip_tx_data *tdata; int res = ast_sip_session_create_invite(session, &tdata); @@ -1532,10 +1534,11 @@ static int call(void *data) ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0); ast_queue_hangup(session->channel); } else { + set_channel_on_rtp_instance(pvt, ast_channel_uniqueid(session->channel)); update_initial_connected_line(session); ast_sip_session_send_request(session, tdata); } - ao2_ref(session, -1); + ao2_ref(channel, -1); return res; } @@ -1544,10 +1547,10 @@ static int chan_pjsip_call(struct ast_channel *ast, const char *dest, int timeou { struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast); - ao2_ref(channel->session, +1); - if (ast_sip_push_task(channel->session->serializer, call, channel->session)) { + ao2_ref(channel, +1); + if (ast_sip_push_task(channel->session->serializer, call, channel)) { ast_log(LOG_WARNING, "Error attempting to place outbound call to call '%s'\n", dest); - ao2_cleanup(channel->session); + ao2_cleanup(channel); return -1; } @@ -1632,12 +1635,7 @@ static struct hangup_data *hangup_data_alloc(int cause, struct ast_channel *chan static void clear_session_and_channel(struct ast_sip_session *session, struct ast_channel *ast, struct chan_pjsip_pvt *pvt) { session->channel = NULL; - if (pvt->media[SIP_MEDIA_AUDIO] && pvt->media[SIP_MEDIA_AUDIO]->rtp) { - ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_AUDIO]->rtp, ""); - } - if (pvt->media[SIP_MEDIA_VIDEO] && pvt->media[SIP_MEDIA_VIDEO]->rtp) { - ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ""); - } + set_channel_on_rtp_instance(pvt, ""); ast_channel_tech_pvt_set(ast, NULL); } |