react-native-webrtc / react-native-webrtc

The WebRTC module for React Native
https://react-native-webrtc.discourse.group
MIT License
4.5k stars 1.22k forks source link

Crash in libjingle when dialing outbound audio call #1566

Open kross-italk opened 1 week ago

kross-italk commented 1 week ago

Expected Behavior:

Using react-native, react-native-webrtc, and sip.js I'm trying to make a call to a known PJSIP endpoint on Asterisk 20.x. It is a known working configuration in a browser, and using react-native-webrtc with the Hermes engine, we get a fatal crash inside libjingle.

Observed Behavior:

This seems similar if not the same as https://github.com/react-native-webrtc/react-native-webrtc/issues/1553

When running under Metro in debug mode, the whole metro process is abruptly ended and development must be reloaded. When built for production, the app does not forcibly exit. This is the only way to get the ADB stacktrace for what's really happening here. It looks like a lack of permissions, but I'm not sure which ones.

05-07 14:25:05.418 25952 26004 F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 26004 (network_thread ), pid 25952 (m.app_mobile)
05-07 14:25:05.455 26131 26131 E DEBUG   : failed to readlink /proc/26004/fd/150: No such file or directory

Steps to reproduce the issue:

These dependencies:

    "react": "18.2.0",
    "react-native": "0.73.6",
    "react-native-volume-manager": "^1.10.0",
    "react-native-webrtc": "^118.0.7",
    "sip.js": "^0.21.2"

Audio only for my use case. Video crashes the same way.

sessionDescriptionHandlerOptions: {
        constraints: {
          audio: true,
          video: false
        }
      },

Following #1553 I tried different codecs. The preference is opus/48000 but the same crash occurs using all allowed media types in the negotiation.

A very basic Android app with a Connect button that uses SIP.JS to connect to a WebRTC Asterisk server. Android SDK 34 Android Platform tools 34 & 31

Complete SIP.JS logs, including SDP is attached in sipjs.log ADB stack trace showing the crash originating in libjingle_peerconnection_so due to a read error on the /proc files.

sipjs.log android-debug.log

kross-italk commented 1 week ago

I was pretty certain this was a permissions issue, and it was. I tediously combed through https://developer.android.com/reference/android/Manifest.permission this list hoping to find anything relevant to my cause.

I selected quite a few permissions, but in the end all I needed was:

    <uses-feature android:name="android.hardware.microphone" />
    <uses-feature android:name="android.hardware.audio.output" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

In my main app manifest. The question remains, what will be needed to accomplish the same on iOS? Time will tell.

8BallBomBom commented 1 week ago

Hmmmmm shouldn't really be getting crashes due to permissions 🤔 But it is also in the docs to manually add permissions over here.

kross-italk commented 1 week ago

FWIW the problem re-appears when compiled for release. I was only able to subvert the crash under Metro.

kross-italk commented 1 week ago

I had to copy the same exemption for a self-signed Certificate Authority for release as debug.

I'll keep it open if you think there's a legitimate crash bug which should be patched.

8BallBomBom commented 1 week ago

Sadly the crash log doesn't always help much. Can you provide more info?

Based on the logs you've shown and as stated above ^ it does indeed appear that the crash is occurring after setting the local session description 🤔

kross-italk commented 1 week ago

I can provide whatever you need, but I will need instructions on which filters to apply to ADB to see what you need. I can confirm that with the permissions set described, the crash is not random and happens each and every time in the same code area. Appreciate the second look. Thanks

8BallBomBom commented 1 week ago

Can you provide a snippet of the code area causing the crash? As for the logcat, an unfiltered log only filtering your app from launch up until the crash is more than good enough 👍🏻 Also is the session description that you included inside the log, is that the session description before modifications?

kross-italk commented 1 week ago

As to the specific code, you'll have to inquire into the depths of SIP.JS. But, I'm here with you as a significant user of that code. In my app, all I do to trigger the bug is to make an invite (WSS, DTLS) using Stock SIP.JS 0.21.2. https://github.com/onsip/SIP.js/blob/2e1c525279c8d6deebb6ecaf3d14477ab7b63310/src/api/inviter.ts#L394

My code shape is something like

if ( connectionState === 'REQUEST_CONNECT' && prevStatus === 'IDLE' ) {
      this.connect();
    } else if ( connectionState === 'REQUEST_DISCONNECT' && prevStatus !== 'REQUEST_DISCONNECT' ) {
      this.disconnect();
    } else if ( connectionState === 'REGISTER' && prevStatus === 'REQUEST_CONNECT' ) {
      this.register();
    } else if ( connectionState === 'REGISTERED' && prevStatus === 'REGISTER' ) {
      this.subscribe();
    }

// Following all the SIP.JS docs to get connected and registered. 
// The specific code is
console.info( `Dialing 0600@192.168.1.100` );
    this.session = new Inviter( this.ua, sipUri );
    this.session.invite( options )

I narrowed it down to this permission: android.permission.ACCESS_NETWORK_STATE

kross-italk commented 1 week ago

Also is the session description that you included inside the log, is that the session description before modifications?

Yes, I am logging the SDP and passing it along unmodified

I think I've better isolated the crash log for you. Attached. webrtc-crash.log

kross-italk commented 1 week ago

Oops, upload error? webrtc-crash.log

saghul commented 1 week ago
05-09 08:28:40.396 22914 22969 W System.err: java.lang.SecurityException: ConnectivityService: Neither user 10412 nor current process has android.permission.ACCESS_NETWORK_STATE.

Did you enable this permission in your manifest? It's necessary.