Platforms & recovery
Platform matrix
Section titled “Platform matrix”| Capability | iOS | Android | Web (react-native-web) |
|---|---|---|---|
| Media | react-native-webrtc | react-native-webrtc | Browser WebRTC (HTTPS/localhost) |
| Microphone permission | System prompt once; then Settings | Runtime prompt; “Don’t ask again” → Settings | Browser prompt |
| Speaker routing | Audio session adapter | Audio session adapter | Output device selection |
| DTMF | SIP INFO (automatic) | SIP INFO (automatic) | RFC 2833 |
| Haptics | Adapter (e.g. expo-haptics) | Built in | navigator.vibrate where supported |
| Synthesized tones | With react-native-audio-api |
With react-native-audio-api |
Built in |
| Expo Go | Preview only | Preview only | – |
Permissions
Section titled “Permissions”The phone never captures audio on launch or registration. It requests the microphone when someone dials or answers, or when they press Check microphone access in audio settings.
state.microphone |
Meaning | UI |
|---|---|---|
requesting |
Prompt is showing (30 s limit) | “Waiting for microphone…” |
granted |
Allowed | – |
denied |
Declined this time; can ask again | Error with retry guidance |
blocked |
iOS denied, or Android “Don’t ask again” | Error plus Open Settings (client.openSettings()) |
unavailable |
No device, busy, or timed out | Error explaining the cause |
Calls while in the background
Section titled “Calls while in the background”Mobile systems suspend JavaScript in the background, so a WebSocket SIP registration cannot reliably ring a sleeping phone. The phone re-registers when the app returns to the foreground (refreshOnForeground, default on) and keeps active calls running with UIBackgroundModes: ["audio", "voip"] on iOS.
For incoming calls while the app is closed, add push wake-up and system call UI:
- Your PBX or a push service sends a VoIP push (PushKit) or high-priority FCM message.
- Show the system UI with react-native-callkeep and connect the client.
- Wire CallKeep’s answer/end actions to
client.answer()/client.hangup(), and useonIncomingCall/onDisconnectedto keep CallKit in sync.
This needs server-side push support and is outside this package.
Recovery
Section titled “Recovery”| Problem | What the phone does |
|---|---|
| Wrong credentials (401/403/404) | Stops, connection: "error", asks to check identity, username, and password |
| Server silent / TLS failure | Times out after registrationTimeoutMs (20 s), stops the agent |
| Socket drops | Ends media, reconnecting, bounded retries (maxReconnectAttempts, 5) |
| Registration lapses in background | Re-registers on foreground |
| ICE fails / disconnects for 10 s | Ends the call with STUN/TURN guidance |
| Microphone unplugged mid-call | Ends the call and explains |
| Transfer fails or times out (30 s) | Keeps the call connected |
| Second incoming call | 486 Busy Here |
| WebRTC missing (Expo Go) | unsupported error naming react-native-webrtc and a development build |
Errors are sanitized: no SIP messages, SDP, or passwords reach callbacks or the UI.
Production checklist
Section titled “Production checklist”- Use
wss://with a valid certificate (plainws://is accepted only forlocalhost,127.0.0.1,[::1], and the Android emulator host10.0.2.2). - Provide TURN servers (
iceServers) for mobile networks behind carrier NAT. - Enable WebRTC on the PBX endpoint (for Asterisk PJSIP:
webrtc=yes, DTLS, and the WSS transport). - Test on real devices with your PBX: routing, two-way audio, hold, DTMF, and REFER transfer.