@voipsdk/react-native-voipcloud 1.0.6 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,33 @@ All notable changes to `@voipsdk/react-native-voipcloud` are documented here.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.8] - 2026-08-26
|
|
9
|
+
Update libraries voipcloud-release.aar 16kb for android
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## [1.0.7] - 2026-08-13
|
|
13
|
+
|
|
14
|
+
Folds in the SDP bandwidth-modifier fixes that were living as app-side
|
|
15
|
+
`patch-package` patches (`@voipsdk+react-native-voipcloud+1.0.6.patch`), so a
|
|
16
|
+
fresh install behaves correctly without any patch. Root-cause mitigation for a
|
|
17
|
+
malformed `b=` line (e.g. `=:40` / `=:4000` / `:=4000`) that some PBX/proxy SDP
|
|
18
|
+
rewriters produce and that breaks SDP parsing / call negotiation.
|
|
19
|
+
|
|
20
|
+
### Changed / Fixed
|
|
21
|
+
|
|
22
|
+
- **iOS:** disable pjmedia's `b=TIAS:<bps>` SDP bandwidth modifier by setting
|
|
23
|
+
`pjmedia_add_bandwidth_tias_in_sdp = PJ_FALSE` right after `libInit`. pjmedia
|
|
24
|
+
stamps that line onto every SDP we author (offer + answer), and some
|
|
25
|
+
PBX/proxy SDP rewriters mangle it (leaving `=:40` / `=:4000`) → corrupt SDP /
|
|
26
|
+
broken call info. We never rely on TIAS, so it is disabled at the source; only
|
|
27
|
+
SDP we author is affected, remote SDP is untouched.
|
|
28
|
+
- **Android:** `ManagedCall.onCallSdpCreated` now sanitizes both the local and
|
|
29
|
+
the remote SDP just before/after negotiation (`sanitizeSdp`). It keeps only
|
|
30
|
+
strictly RFC 4566 well-formed `<type>=<value>` lines (single `a-z` key,
|
|
31
|
+
non-empty value) and drops every bandwidth (`b=`) line, so a single corrupt
|
|
32
|
+
line can never invalidate the whole SDP. Line endings are normalized to CRLF
|
|
33
|
+
and the session is only rewritten when something actually changed.
|
|
34
|
+
|
|
8
35
|
## [1.0.6] - 2026-08-10
|
|
9
36
|
|
|
10
37
|
Folds in the push-wake registration-refresh fixes that were living as an app-side
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @voipsdk/react-native-voipcloud
|
|
2
2
|
|
|
3
3
|
> Public VoIP SDK for React Native — Android **and** iOS (RN 0.70+).
|
|
4
|
-
> Package: `@voipsdk/react-native-voipcloud@1.0.
|
|
4
|
+
> Package: `@voipsdk/react-native-voipcloud@1.0.7`
|
|
5
5
|
|
|
6
6
|
Android and iOS expose the **same** JS API, events and `VC_*` error codes.
|
|
7
7
|
|
|
@@ -12,9 +12,11 @@ import com.voipcloud.sdk.CallInfo;
|
|
|
12
12
|
import com.voipcloud.sdk.CallMediaInfo;
|
|
13
13
|
import com.voipcloud.sdk.Endpoint;
|
|
14
14
|
import com.voipcloud.sdk.OnCallMediaStateParam;
|
|
15
|
+
import com.voipcloud.sdk.OnCallSdpCreatedParam;
|
|
15
16
|
import com.voipcloud.sdk.OnCallStateParam;
|
|
16
17
|
import com.voipcloud.sdk.OnCallTransferStatusParam;
|
|
17
18
|
import com.voipcloud.sdk.OnDtmfDigitParam;
|
|
19
|
+
import com.voipcloud.sdk.SdpSession;
|
|
18
20
|
import com.voipcloud.sdk.pjmedia_type;
|
|
19
21
|
import com.voipcloud.sdk.pjsip_inv_state;
|
|
20
22
|
import com.voipcloud.sdk.pjsua_call_media_status;
|
|
@@ -189,6 +191,72 @@ public final class ManagedCall extends Call {
|
|
|
189
191
|
emitMediaState();
|
|
190
192
|
}
|
|
191
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Fired after PJSIP builds the local SDP (our offer for outgoing calls, our
|
|
196
|
+
* answer for incoming ones, and re-offer/answer on hold/unhold) but BEFORE
|
|
197
|
+
* it is sent. We sanitize both the SDP we send and PJSIP's copy of the
|
|
198
|
+
* remote SDP so a malformed line or a bandwidth modifier can never break
|
|
199
|
+
* negotiation — see {@link #sanitizeSdp}.
|
|
200
|
+
*/
|
|
201
|
+
@Override
|
|
202
|
+
public void onCallSdpCreated(OnCallSdpCreatedParam prm) {
|
|
203
|
+
try {
|
|
204
|
+
sanitizeSdp(prm.getSdp());
|
|
205
|
+
sanitizeSdp(prm.getRemSdp());
|
|
206
|
+
} catch (Throwable ignored) {}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Rewrite an SdpSession in place, keeping ONLY strictly well-formed lines
|
|
211
|
+
* and dropping every bandwidth ("b=") line.
|
|
212
|
+
*
|
|
213
|
+
* Per RFC 4566 every SDP line is {@code <type>=<value>} where {@code <type>}
|
|
214
|
+
* is exactly one letter and {@code <value>} is non-empty. We enforce that
|
|
215
|
+
* grammar and treat anything else as corruption to be removed — not just the
|
|
216
|
+
* one observed artifact ({@code :=4000}) but ANY bad key or value:
|
|
217
|
+
* <ul>
|
|
218
|
+
* <li>key is not a single {@code a-z} letter — {@code :=4}, {@code S=4},
|
|
219
|
+
* {@code =64000}, {@code 3=x}, {@code " b=…"} (leading space)…</li>
|
|
220
|
+
* <li>second char is not {@code '='} — {@code ba=…}, {@code b:AS…}…</li>
|
|
221
|
+
* <li>empty value — {@code a=} with nothing after {@code '='}</li>
|
|
222
|
+
* </ul>
|
|
223
|
+
* Dropping a bad line (rather than trusting it) means a single corrupt line
|
|
224
|
+
* can never invalidate the whole SDP, and the value it carried is irrelevant.
|
|
225
|
+
* Line endings are normalized to CRLF. No-op when the SDP is absent; the
|
|
226
|
+
* session is only rewritten if something actually changed.
|
|
227
|
+
*/
|
|
228
|
+
private static void sanitizeSdp(SdpSession session) {
|
|
229
|
+
if (session == null) return;
|
|
230
|
+
String sdp;
|
|
231
|
+
try { sdp = session.getWholeSdp(); } catch (Throwable e) { return; }
|
|
232
|
+
if (sdp == null || sdp.isEmpty()) return;
|
|
233
|
+
|
|
234
|
+
// Split on any newline style (CRLF / CR / LF) so a stray ending cannot
|
|
235
|
+
// smuggle a corrupt token through as part of another line.
|
|
236
|
+
String[] lines = sdp.split("\r\n|\r|\n");
|
|
237
|
+
StringBuilder out = new StringBuilder(sdp.length());
|
|
238
|
+
boolean changed = false;
|
|
239
|
+
for (String line : lines) {
|
|
240
|
+
int len = line.length();
|
|
241
|
+
if (len == 0) { continue; }
|
|
242
|
+
char key = line.charAt(0);
|
|
243
|
+
boolean wellFormed =
|
|
244
|
+
len >= 3 // key + '=' + at least one value char
|
|
245
|
+
&& line.charAt(1) == '=' // "<key>=" separator
|
|
246
|
+
&& key >= 'a' && key <= 'z'; // key is a single a-z letter only
|
|
247
|
+
if (!wellFormed || key == 'b') { // corrupt/invalid line, or bandwidth
|
|
248
|
+
changed = true;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
out.append(line).append("\r\n");
|
|
252
|
+
}
|
|
253
|
+
// Only push back a non-empty result; a real SDP always keeps v=/o=/… so
|
|
254
|
+
// out is never empty in practice, but guard against wiping the session.
|
|
255
|
+
if (changed && out.length() > 0) {
|
|
256
|
+
try { session.setWholeSdp(out.toString()); } catch (Throwable ignored) {}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
192
260
|
/**
|
|
193
261
|
* Multi-stage progress notifications for a REFER (call transfer)
|
|
194
262
|
* we initiated. Fires for each NOTIFY received from the remote
|
|
Binary file
|
package/ios/VoipCloudEngine.mm
CHANGED
|
@@ -14,6 +14,15 @@
|
|
|
14
14
|
|
|
15
15
|
using namespace pj;
|
|
16
16
|
|
|
17
|
+
// pjmedia run-time flag (defined in pjmedia endpoint.c, C linkage). Default 1 →
|
|
18
|
+
// pjmedia stamps a "b=TIAS:<bps>" bandwidth modifier onto every SDP it generates
|
|
19
|
+
// (our outgoing offer + our answer). Some PBX/proxy SDP rewriters mangle that line
|
|
20
|
+
// (e.g. leaving "=:40"/"=:4000") → corrupt SDP / broken call info. We never rely on
|
|
21
|
+
// TIAS, so disable at the source. Only touches SDP *we* author; remote SDP is
|
|
22
|
+
// untouched (strip those at the PBX). Declared here because config.h only mentions
|
|
23
|
+
// it in a doc comment, not as a real extern.
|
|
24
|
+
extern "C" pj_bool_t pjmedia_add_bandwidth_tias_in_sdp;
|
|
25
|
+
|
|
17
26
|
static NSString *const kVCErrorDomain = @"VoipCloudEngine";
|
|
18
27
|
|
|
19
28
|
static NSError *VCMakeError(NSInteger code, NSString *msg) {
|
|
@@ -323,6 +332,11 @@ void VCCall::onDtmfDigit(OnDtmfDigitParam &prm) {
|
|
|
323
332
|
|
|
324
333
|
_ep->libInit(epCfg);
|
|
325
334
|
|
|
335
|
+
// Never emit the SDP "b=TIAS:" bandwidth modifier — it triggers broken
|
|
336
|
+
// SDP rewrites downstream (=:40 / =:4000) and we don't use it. Safe to set
|
|
337
|
+
// once the pjmedia endpoint exists (after libInit); read at SDP-gen time.
|
|
338
|
+
pjmedia_add_bandwidth_tias_in_sdp = PJ_FALSE;
|
|
339
|
+
|
|
326
340
|
// Ephemeral ports (0) avoid "Address already in use" for SIP clients.
|
|
327
341
|
// Keep each transport id so registerAccountWithConfig can pin the
|
|
328
342
|
// account to the matching one (0 is a valid id → init to -1).
|