Handle RTP timeout when only using MixMonitor

Hello,

I have a dialplan dedicated to record communications sent to Asterisk, there is no Dial command or anything else like that, but we also use the Playback application to send silence.

The issue is that I need to detect an incoming RTP timeout, to be able to stop the recording.

My dialplan looks like that :

exten => c,n,MixMonitor(/tmp/record.alaw)
exten => c,n,Answer()
exten => c,n,Set(TIMEOUT(response)=10)
exten => c,n,While(1==2)
exten => c,n,Playback(silence/10)
exten => c,n,EndWhile()

Is setting RTP_TIMEOUT would work in this case ? I read somewhere that it would not as monitor the incoming rtp stream, and that I could trick that by using a Dial command to a dummy destination.

The way we designed this plan, is that we try to record endlessly, until the remote party close the call, but we have issues when we don’t receive a sip bye, that’s why we try to monitor a incoming rtp timeout.

How would I do that ? (I am using Asterisk 22)

PS : should I put Answer before or after MixMonitor ?

Thanks.

If you set rtp_timeout on the endpoint, then yes. It would terminate the call if incoming RTP was not received for the given period of time. It doesn’t matter if they’re bridged or connected to other stuff or not.

This doesn’t really do anything here either for your usage.

It doesn’t matter.

I am sorry, I found out that setting RTP_TIMEOUT is only valid for a dialplan using chan_sip, I am using chan_pjsip, so Asterisk tells me this function is not registered.

I saw that in fact you told me to set rtp_timeout on the endpoint, and this is what I did :

vp195*CLI> pjsip show endpoint trunk_3232041677

 Endpoint:  <Endpoint/CID.....................................>  <State.....>  <Channels.>
    I/OAuth:  <AuthId/UserName...........................................................>
        Aor:  <Aor............................................>  <MaxContact>
      Contact:  <Aor/ContactUri..........................> <Hash....> <Status> <RTT(ms)..>
  Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress..................>
   Identify:  <Identify/Endpoint.........................................................>
        Match:  <criteria.........................>
    Channel:  <ChannelId......................................>  <State.....>  <Time.....>
        Exten: <DialedExten...........>  CLCID: <ConnectedLineCID.......>
==========================================================================================

 Endpoint:  trunk_3232041677                                     Not in use    0 of inf
        Aor:  trunk_3232041677                                   0
      Contact:  trunk_3232041677/sip:192.165.10.205:5060   f679743a90 Avail         1.340
   Identify:  trunk_3232041677/trunk_3232041677
        Match: 192.165.10.205/32


 ParameterName                      : ParameterValue
 ===================================================================================================
 100rel                             : yes
 accept_multiple_sdp_answers        : false
 accountcode                        : 
 acl                                : 
 aggregate_mwi                      : true
 allow                              : (ulaw|alaw)
 allow_overlap                      : true
 allow_subscribe                    : true
 allow_transfer                     : true
 allow_unauthenticated_options      : false
 aors                               : trunk_3232041677
 asymmetric_rtp_codec               : false
 auth                               : 
 bind_rtp_to_media_address          : false
 bundle                             : false
 call_group                         : 
 callerid                           : <unknown>
 callerid_privacy                   : allowed_not_screened
 callerid_tag                       : 
 codec_prefs_incoming_answer        : prefer:pending, operation:intersect, keep:all, transcode:allow
 codec_prefs_incoming_offer         : prefer:pending, operation:intersect, keep:all, transcode:allow
 codec_prefs_outgoing_answer        : prefer:pending, operation:intersect, keep:all, transcode:allow
 codec_prefs_outgoing_offer         : prefer:pending, operation:union, keep:all, transcode:allow
 connected_line_method              : invite
 contact_acl                        : 
 context                            : sip_trunksip
 cos_audio                          : 0
 cos_video                          : 0
 device_state_busy_at               : 0
 direct_media                       : true
 direct_media_glare_mitigation      : none
 direct_media_method                : invite
 disable_direct_media_on_nat        : false
 dtls_auto_generate_cert            : No
 dtls_ca_file                       : 
 dtls_ca_path                       : 
 dtls_cert_file                     : 
 dtls_cipher                        : 
 dtls_fingerprint                   : SHA-256
 dtls_private_key                   : 
 dtls_rekey                         : 0
 dtls_setup                         : active
 dtls_verify                        : No
 dtmf_mode                          : rfc4733
 fax_detect                         : false
 fax_detect_timeout                 : 0
 follow_early_media_fork            : true
 force_avp                          : false
 force_rport                        : true
 from_domain                        : 
 from_user                          : 
 g726_non_standard                  : false
 geoloc_incoming_call_profile       : 
 geoloc_outgoing_call_profile       : 
 ice_support                        : false
 identify_by                        : username,ip
 ignore_183_without_sdp             : false
 inband_progress                    : false
 incoming_call_offer_pref           : local
 incoming_mwi_mailbox               : 
 language                           : 
 mailboxes                          : 
 max_audio_streams                  : 1
 max_video_streams                  : 1
 media_address                      : 
 media_encryption                   : no
 media_encryption_optimistic        : false
 media_use_received_transport       : false
 message_context                    : 
 moh_passthrough                    : false
 moh_suggest                        : default
 mwi_from_user                      : 
 mwi_subscribe_replaces_unsolicited : no
 named_call_group                   : 
 named_pickup_group                 : 
 notify_early_inuse_ringing         : false
 one_touch_recording                : false
 outbound_auth                      : 
 outbound_proxy                     : 
 outgoing_call_offer_pref           : remote_merge
 overlap_context                    : 
 pickup_group                       : 
 preferred_codec_only               : false
 record_off_feature                 : automixmon
 record_on_feature                  : automixmon
 refer_blind_progress               : true
 rewrite_contact                    : false
 rpid_immediate                     : false
 rtcp_mux                           : false
 rtp_engine                         : asterisk
 rtp_ipv6                           : false
 rtp_keepalive                      : 0
 rtp_symmetric                      : false
 rtp_timeout                        : 5
 rtp_timeout_hold                   : 0
 sdp_owner                          : -
 sdp_session                        : Asterisk
 security_negotiation               : no
 send_aoc                           : false
 send_connected_line                : yes
 send_diversion                     : true
 send_history_info                  : false
 send_pai                           : false
 send_rpid                          : false
 set_var                            : 
 srtp_tag_32                        : false
 stir_shaken                        : no
 stir_shaken_profile                : 
 sub_min_expiry                     : 0
 subscribe_context                  : 
 suppress_moh_on_sendonly           : false
 suppress_q850_reason_headers       : false
 t38_bind_udptl_to_media_address    : false
 t38_udptl                          : false
 t38_udptl_ec                       : none
 t38_udptl_ipv6                     : false
 t38_udptl_maxdatagram              : 0
 t38_udptl_nat                      : false
 tenantid                           : 
 timers                             : yes
 timers_min_se                      : 90
 timers_sess_expires                : 1800
 tone_zone                          : 
 tos_audio                          : 0
 tos_video                          : 0
 transport                          : 
 trust_connected_line               : yes
 trust_id_inbound                   : false
 trust_id_outbound                  : false
 use_avpf                           : false
 use_ptime                          : false
 user_eq_phone                      : false
 voicemail_extension                : 
 webrtc                             : no

So, here is my endpoint, but it doesn’t seems to do anything, could the fact that we are sending RTP via the Playback function be the issue ?

The endpoint is defined like so :

[trunk_3232041677]
type=endpoint
context=sip_trunksip
rtp_timeout=5
disallow=all
allow=ulaw
allow=alaw
aors=trunk_3232041677

[trunk_3232041677]
type=aor
qualify_frequency=60
contact=sip:192.165.10.205:5060


[trunk_3232041677]
type=identify
endpoint=trunk_3232041677
match=192.165.10.205

It looks at the received RTP. So, verify that RTP isn’t actually flowing using “rtp set debug on” inbound for it.

This show me that Asterisk is sending RTP but the debug don’t see any RTP received, but I know there are, as my mixmonitor files contains what have been sent to asterisk.

If RTP is being received… then I’d expect it to show up there…

Indeed, and you are right, this is my mistake, for the context, I am trying to simulate the case where RTP is not sent from the remote client, for that I am using StarTrinity Sip Tester.

In this tool, to simulate a RTP packet loss, I am using a command that set the probability that a RTP packet is lost to 100%, I didn’t know that this was a global set, once it’s set, it’s still set for all the following tests, I just have to set the same probability to 0% at the beginning of the test script.

I am really sorry for this.

So, indeed, rtp debug show that I receive RTP (from sip tester) and that I send RTP (the playback).

How can I see that asterisk is closing the call on rtp timeout ?

I have read somewhere that MixMonitor will not be enough to be able to make rtp_timeout works, and that I need to bridge to something

so I have created a dummy context :

[dummy]
exten => silence,1,Progress()
  same => n,MusicOnHold(silence)
  same => n,Goto(silence,1)

and my plan have been modified like so :

  same => n,Answer()
  same => n,MixMonitor(/tmp/record.alaw)
  same => n,Dial(Local/silence@dummy)
  same => n(loop),Wait(1)
  same => n,Goto(loop)

But this doesn’t works either, my test cut the rtp sent to asterisk after 7 seconds, and end the call 20 seconds after that, the rtp_timeout on my endpoint is set to 5, and yet, with a dumpchan app call, the call was of 27 seconds, where I would expect it to be 7 + 5 = 12 seconds.

What do I do wrong ?

A bridge is not required. Where are you getting that information?

You need to show more, such as the “rtp set debug on” I mentioned before to confirm it’s not coming in. A debug log[1] may also show stuff.

[1] Collecting Debug Information - Asterisk Documentation

rtp_timeout.txt (185.8 KB)

I don’t remember where I found that, so I put back the plan like initial, and did a test, this file is the result from the cli, I will try to see how to get the log files that you asked.

And the output of “pjsip show endpoint trunk_3232041677_endpoint”?

pjsip show endpoint trunk_3232041677_endpoint 

 Endpoint:  <Endpoint/CID.....................................>  <State.....>  <Channels.>
    I/OAuth:  <AuthId/UserName...........................................................>
        Aor:  <Aor............................................>  <MaxContact>
      Contact:  <Aor/ContactUri..........................> <Hash....> <Status> <RTT(ms)..>
  Transport:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress..................>
   Identify:  <Identify/Endpoint.........................................................>
        Match:  <criteria.........................>
    Channel:  <ChannelId......................................>  <State.....>  <Time.....>
        Exten: <DialedExten...........>  CLCID: <ConnectedLineCID.......>
==========================================================================================

 Endpoint:  trunk_3232041677_endpoint                            Not in use    0 of inf
        Aor:  trunk_3232041677_aor                               0
      Contact:  trunk_3232041677_aor/sip:192.165.10.205:50 f679743a90 Avail         1.229
   Identify:  trunk_3232041677_identify/trunk_3232041677_endpoint
        Match: 192.165.10.205/32


 ParameterName                      : ParameterValue
 ===================================================================================================
 100rel                             : yes
 accept_multiple_sdp_answers        : false
 accountcode                        : 
 acl                                : 
 aggregate_mwi                      : true
 allow                              : (ulaw|alaw)
 allow_overlap                      : true
 allow_subscribe                    : true
 allow_transfer                     : true
 allow_unauthenticated_options      : false
 aors                               : trunk_3232041677_aor
 asymmetric_rtp_codec               : false
 auth                               : 
 bind_rtp_to_media_address          : false
 bundle                             : false
 call_group                         : 
 callerid                           : <unknown>
 callerid_privacy                   : allowed_not_screened
 callerid_tag                       : 
 codec_prefs_incoming_answer        : prefer:pending, operation:intersect, keep:all, transcode:allow
 codec_prefs_incoming_offer         : prefer:pending, operation:intersect, keep:all, transcode:allow
 codec_prefs_outgoing_answer        : prefer:pending, operation:intersect, keep:all, transcode:allow
 codec_prefs_outgoing_offer         : prefer:pending, operation:union, keep:all, transcode:allow
 connected_line_method              : invite
 contact_acl                        : 
 context                            : record
 cos_audio                          : 0
 cos_video                          : 0
 device_state_busy_at               : 0
 direct_media                       : false
 direct_media_glare_mitigation      : none
 direct_media_method                : invite
 disable_direct_media_on_nat        : false
 dtls_auto_generate_cert            : No
 dtls_ca_file                       : 
 dtls_ca_path                       : 
 dtls_cert_file                     : 
 dtls_cipher                        : 
 dtls_fingerprint                   : SHA-256
 dtls_private_key                   : 
 dtls_rekey                         : 0
 dtls_setup                         : active
 dtls_verify                        : No
 dtmf_mode                          : rfc4733
 fax_detect                         : false
 fax_detect_timeout                 : 0
 follow_early_media_fork            : true
 force_avp                          : false
 force_rport                        : true
 from_domain                        : 
 from_user                          : 
 g726_non_standard                  : false
 geoloc_incoming_call_profile       : 
 geoloc_outgoing_call_profile       : 
 ice_support                        : false
 identify_by                        : username,ip
 ignore_183_without_sdp             : false
 inband_progress                    : false
 incoming_call_offer_pref           : local
 incoming_mwi_mailbox               : 
 language                           : 
 mailboxes                          : 
 max_audio_streams                  : 1
 max_video_streams                  : 1
 media_address                      : 
 media_encryption                   : no
 media_encryption_optimistic        : false
 media_use_received_transport       : false
 message_context                    : 
 moh_passthrough                    : false
 moh_suggest                        : default
 mwi_from_user                      : 
 mwi_subscribe_replaces_unsolicited : no
 named_call_group                   : 
 named_pickup_group                 : 
 notify_early_inuse_ringing         : false
 one_touch_recording                : false
 outbound_auth                      : 
 outbound_proxy                     : 
 outgoing_call_offer_pref           : remote_merge
 overlap_context                    : 
 pickup_group                       : 
 preferred_codec_only               : false
 record_off_feature                 : automixmon
 record_on_feature                  : automixmon
 refer_blind_progress               : true
 rewrite_contact                    : false
 rpid_immediate                     : false
 rtcp_mux                           : false
 rtp_engine                         : asterisk
 rtp_ipv6                           : false
 rtp_keepalive                      : 5
 rtp_symmetric                      : false
 rtp_timeout                        : 5
 rtp_timeout_hold                   : 5
 sdp_owner                          : -
 sdp_session                        : Asterisk
 security_negotiation               : no
 send_aoc                           : false
 send_connected_line                : yes
 send_diversion                     : true
 send_history_info                  : false
 send_pai                           : false
 send_rpid                          : false
 set_var                            : 
 srtp_tag_32                        : false
 stir_shaken                        : no
 stir_shaken_profile                : 
 sub_min_expiry                     : 0
 subscribe_context                  : 
 suppress_moh_on_sendonly           : false
 suppress_q850_reason_headers       : false
 t38_bind_udptl_to_media_address    : false
 t38_udptl                          : false
 t38_udptl_ec                       : none
 t38_udptl_ipv6                     : false
 t38_udptl_maxdatagram              : 0
 t38_udptl_nat                      : false
 tenantid                           : 
 timers                             : yes
 timers_min_se                      : 90
 timers_sess_expires                : 1800
 tone_zone                          : 
 tos_audio                          : 0
 tos_video                          : 0
 transport                          : 
 trust_connected_line               : yes
 trust_id_inbound                   : false
 trust_id_outbound                  : false
 use_avpf                           : false
 use_ptime                          : false
 user_eq_phone                      : false
 voicemail_extension                : 
 webrtc                             : no

Here is the endpoint.

Definitely need to see a debug log, then.

I hope I did it correctly
(Log file deleted, it contains personal data)

You appear to still be receiving RTCP, so the remote side is considered “still there”. The rtp_timeout setting is if ALL traffic ceases.

Ohh, I am really sorry, I will try to block the rtcp packets too. Thank you for your help.

Ok, Indeed, I can confirm that if I kill my simulator, the rtp_timeout indeed works as expected.

I am really sorry to have bothered you with that.

Is there a way to get the informations about rxcount and rtxcount in the dialplan ? I only get empty values, but when the call is ended, calling a DumpChan give me these stats

When asking for help and you try something, state what you’ve tried.

1 Like

Yes, ok, my plan is like so :

same => n,Answer()
  same => n,MixMonitor(/tmp/record.alaw)
  same => n(loop),Wait(1)
  same => n,Set(RX_COUNT=${RTPAUDIOQOS,rxcount})
  same => n,Set(TX_COUNT=${RTPAUDIOQOS,txcount})
  same => n,NoOp(RTP RX=${RX_COUNT}, TX=${TX_COUNT})
  same => n,Set(JitterIn=${RTPAUDIOQOS,rxjitter})
  same => n,Set(LossPct=${RTPAUDIOQOS,losspct})
  same => n,NoOp(Jitter=${JitterIn} | Perte=${LossPct}%)
  same => n,Goto(loop)

exten => h,1,NoOp(Call ended)
  same => n,DumpChan()
  same => n,Hangup()

on the cli I have that :

[Jul 17 15:36:30]     -- Executing [rec@record:8] Wait("PJSIP/trunk_3232041677_endpoint-00000027", "1") in new stack
[Jul 17 15:36:31]     -- Executing [rec@record:9] Set("PJSIP/trunk_3232041677_endpoint-00000027", "RX_COUNT=") in new stack
[Jul 17 15:36:31]     -- Executing [rec@record:10] Set("PJSIP/trunk_3232041677_endpoint-00000027", "TX_COUNT=") in new stack
[Jul 17 15:36:31]     -- Executing [rec@record:11] NoOp("PJSIP/trunk_3232041677_endpoint-00000027", "RTP RX=, TX=") in new stack
[Jul 17 15:36:31]     -- Executing [rec@record:12] Set("PJSIP/trunk_3232041677_endpoint-00000027", "JitterIn=") in new stack
[Jul 17 15:36:31]     -- Executing [rec@record:13] Set("PJSIP/trunk_3232041677_endpoint-00000027", "LossPct=") in new stack
[Jul 17 15:36:31]     -- Executing [rec@record:14] NoOp("PJSIP/trunk_3232041677_endpoint-00000027", "Jitter= | Perte=%") in new stack
[Jul 17 15:36:31]     -- Executing [rec@record:15] Goto("PJSIP/trunk_3232041677_endpoint-00000027", "loop") in new stack

But, at the end of tha call, DumpChan give me the information I am searching to get :

...
[Jul 17 15:36:31] RTPAUDIOQOS=ssrc=1378857088;themssrc=342437582;lp=0;rxjitter=0.000000;rxcount=204;txjitter=0.006125;txcount=1;rlp=0;rtt=0.000000;rxmes=88.087887;txmes=0.000000
...

My issue is that the RTCP is indeed preventing me to stop the call on RTP timeout, so I wanted to use the rxcount to track a RTP loss and hangup myself