|
44 | 44 | SIP_DIAL_TIMEOUT = 30.0 |
45 | 45 | """@private""" |
46 | 46 |
|
| 47 | +# A dialing request must outlast the ringing window, or it would abort before |
| 48 | +# the call can be answered. Keep the request timeout at least this many seconds |
| 49 | +# above the request's ringing_timeout. |
| 50 | +RINGING_TIMEOUT_MARGIN = 2.0 |
| 51 | +"""@private""" |
| 52 | + |
| 53 | + |
| 54 | +def _dial_timeout(user_timeout: Optional[float], request) -> float: |
| 55 | + """Request timeout (seconds) for a phone-dialing call: the user-supplied |
| 56 | + value (or the dial default) raised, when needed, to stay at least |
| 57 | + RINGING_TIMEOUT_MARGIN above the request's ringing_timeout.""" |
| 58 | + effective = user_timeout if user_timeout else SIP_DIAL_TIMEOUT |
| 59 | + if request.HasField("ringing_timeout"): |
| 60 | + effective = max(effective, request.ringing_timeout.seconds + RINGING_TIMEOUT_MARGIN) |
| 61 | + return effective |
| 62 | + |
47 | 63 |
|
48 | 64 | class SipService(Service): |
49 | 65 | """Client for LiveKit SIP Service API |
@@ -785,13 +801,13 @@ async def create_sip_participant( |
785 | 801 | SIPError: If the SIP operation fails |
786 | 802 | """ |
787 | 803 | client_timeout: Optional[aiohttp.ClientTimeout] = None |
788 | | - if timeout: |
| 804 | + if create.wait_until_answered: |
| 805 | + # Dialing a phone and waiting for an answer takes longer than a |
| 806 | + # normal call, and the request must outlast ringing. |
| 807 | + client_timeout = aiohttp.ClientTimeout(total=_dial_timeout(timeout, create)) |
| 808 | + elif timeout: |
789 | 809 | # obey user specified timeout |
790 | 810 | client_timeout = aiohttp.ClientTimeout(total=timeout) |
791 | | - elif create.wait_until_answered: |
792 | | - # Dialing a phone and waiting for an answer takes longer than a |
793 | | - # normal call, so use a longer default. |
794 | | - client_timeout = aiohttp.ClientTimeout(total=SIP_DIAL_TIMEOUT) |
795 | 811 |
|
796 | 812 | if trunk_id: |
797 | 813 | create.sip_trunk_id = trunk_id |
@@ -826,8 +842,9 @@ async def transfer_sip_participant( |
826 | 842 | Updated SIP participant information |
827 | 843 | """ |
828 | 844 | # Transferring a call dials a phone, which takes longer than a normal |
829 | | - # call, so use a longer default unless the user specified a timeout. |
830 | | - client_timeout = aiohttp.ClientTimeout(total=timeout if timeout else SIP_DIAL_TIMEOUT) |
| 845 | + # call, so use a longer default unless the user specified a timeout, and |
| 846 | + # keep the request alive past ringing so the destination can answer. |
| 847 | + client_timeout = aiohttp.ClientTimeout(total=_dial_timeout(timeout, transfer)) |
831 | 848 | return await self._client.request( |
832 | 849 | SVC, |
833 | 850 | "TransferSIPParticipant", |
|
0 commit comments