home-assistant-libs / voip-utils

Apache License 2.0
1 stars 5 forks source link

voip clients that do not support opus should be rejected #14

Open realumhelp opened 1 year ago

realumhelp commented 1 year ago

I have an old OBI200 I was going to try to integrate with voip to play with the voice features.

After playing around with the device and configuring it in such a way to get HA to accept the SIP INVITE the device gets added to into HA. image

However, the device is cannot be used because it does not support the opus codec. Now anytime I try to use the device I get opus errors which makes sense but... I'd argue the process shouldn't have even gotten this far.

2023-05-31 02:44:09.028 ERROR (MainThread) [homeassistant] Error doing job: Exception in callback None()
Traceback (most recent call last):
File "/usr/local/lib/python3.10/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.10/asyncio/selector_events.py", line 1035, in _read_ready
self._protocol.datagram_received(data, addr)
File "/usr/local/lib/python3.10/site-packages/voip_utils/voip.py", line 131, in datagram_received
raise err
File "/usr/local/lib/python3.10/site-packages/voip_utils/voip.py", line 121, in datagram_received
audio_bytes = self._rtp_input.process_packet(
File "/usr/local/lib/python3.10/site-packages/voip_utils/rtp_audio.py", line 70, in process_packet
audio_bytes = opuslib.api.decoder.decode(
File "/usr/local/lib/python3.10/site-packages/opuslib/api/decoder.py", line 246, in decode
raise opuslib.exceptions.OpusError(result)
opuslib.exceptions.OpusError: b'corrupted stream'

During the INVITE stage the device should be automatically rejected because it does not support opus in the media format list. image

It looks like the code already kinda does look for opus as a media type but does not throw an error if it is not found:

# a=rtpmap:123 opus/48000/2
                        codec_str = value.split(":", maxsplit=1)[1]
                        codec_parts = codec_str.split()
                        if (len(codec_parts) > 1) and (
                            codec_parts[1].lower().startswith("opus")
                        ):
                            opus_payload_type = int(codec_parts[0])
                            _LOGGER.debug(
                                "Detected OPUS payload type as %s", opus_payload_type
                            )

In theory it should be easy to check if opus was found or not after looping through the media_format list. It would be nice to read an error that says device doesn't support opus rather than giving me false hope this thing will work.