@bits-innovate/react-native-vstarcam 1.0.15 → 1.0.17
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.
|
@@ -13,13 +13,21 @@ import com.facebook.react.bridge.ReactMethod;
|
|
|
13
13
|
import com.facebook.react.bridge.WritableMap;
|
|
14
14
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
15
15
|
|
|
16
|
+
import java.io.BufferedReader;
|
|
17
|
+
import java.io.InputStreamReader;
|
|
16
18
|
import java.lang.reflect.InvocationHandler;
|
|
17
19
|
import java.lang.reflect.Method;
|
|
18
20
|
import java.lang.reflect.Proxy;
|
|
21
|
+
import java.net.HttpURLConnection;
|
|
22
|
+
import java.net.URL;
|
|
19
23
|
import java.util.HashMap;
|
|
20
24
|
import java.util.Map;
|
|
21
25
|
import java.util.concurrent.ExecutorService;
|
|
22
26
|
import java.util.concurrent.Executors;
|
|
27
|
+
import java.util.regex.Pattern;
|
|
28
|
+
|
|
29
|
+
import org.json.JSONObject;
|
|
30
|
+
|
|
23
31
|
|
|
24
32
|
/**
|
|
25
33
|
* VStarCam React Native Module
|
|
@@ -78,6 +86,56 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
78
86
|
return param;
|
|
79
87
|
}
|
|
80
88
|
|
|
89
|
+
// Pattern to detect virtual UIDs (like ACAE0001151GWYQ)
|
|
90
|
+
// Virtual UIDs: start with letters, have 7+ digits, end with letters
|
|
91
|
+
private static final Pattern VIRTUAL_UID_PATTERN = Pattern.compile("^[a-zA-Z]{1,}\\d{7,}.*[a-zA-Z]$");
|
|
92
|
+
|
|
93
|
+
// Check if a device ID is a virtual UID that needs conversion
|
|
94
|
+
private static boolean isVirtualId(String deviceId) {
|
|
95
|
+
if (deviceId == null || deviceId.length() < 10) return false;
|
|
96
|
+
return VIRTUAL_UID_PATTERN.matcher(deviceId).matches();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Convert virtual UID to real client ID using VStarCam API
|
|
100
|
+
// Returns: {uid, supplier, cluster} or null on failure
|
|
101
|
+
private String[] convertVirtualUid(String virtualUid) {
|
|
102
|
+
try {
|
|
103
|
+
URL url = new URL("https://vuid.eye4.cn?vuid=" + virtualUid);
|
|
104
|
+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
105
|
+
conn.setRequestMethod("GET");
|
|
106
|
+
conn.setConnectTimeout(10000);
|
|
107
|
+
conn.setReadTimeout(10000);
|
|
108
|
+
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
|
109
|
+
|
|
110
|
+
int responseCode = conn.getResponseCode();
|
|
111
|
+
if (responseCode == 200) {
|
|
112
|
+
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
|
113
|
+
StringBuilder response = new StringBuilder();
|
|
114
|
+
String line;
|
|
115
|
+
while ((line = reader.readLine()) != null) {
|
|
116
|
+
response.append(line);
|
|
117
|
+
}
|
|
118
|
+
reader.close();
|
|
119
|
+
|
|
120
|
+
JSONObject json = new JSONObject(response.toString());
|
|
121
|
+
String uid = json.optString("uid", null);
|
|
122
|
+
String supplier = json.optString("supplier", "");
|
|
123
|
+
String cluster = json.optString("cluster", "");
|
|
124
|
+
|
|
125
|
+
if (uid != null && !uid.isEmpty()) {
|
|
126
|
+
Log.d(TAG, "Converted virtual UID " + virtualUid + " -> real UID: " + uid + " (supplier: " + supplier + ", cluster: " + cluster + ")");
|
|
127
|
+
return new String[]{uid, supplier, cluster};
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
Log.e(TAG, "Virtual UID conversion failed, HTTP " + responseCode);
|
|
131
|
+
}
|
|
132
|
+
conn.disconnect();
|
|
133
|
+
} catch (Exception e) {
|
|
134
|
+
Log.e(TAG, "Failed to convert virtual UID: " + e.getMessage(), e);
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
81
139
|
private final ReactApplicationContext reactContext;
|
|
82
140
|
private final ExecutorService executor;
|
|
83
141
|
|
|
@@ -93,12 +151,14 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
93
151
|
private Class<?> releaseListenerClass = null;
|
|
94
152
|
|
|
95
153
|
private static class ClientInfo {
|
|
96
|
-
String deviceId;
|
|
97
|
-
|
|
154
|
+
String deviceId; // Original device ID (can be virtual UID)
|
|
155
|
+
String realClientId; // Converted client ID (for JNI calls)
|
|
156
|
+
long sdkClientPtr = 0; // Actual SDK client pointer (long)
|
|
98
157
|
boolean isConnected = false;
|
|
99
158
|
boolean isLoggedIn = false;
|
|
100
159
|
}
|
|
101
160
|
|
|
161
|
+
|
|
102
162
|
public VStarCamModule(ReactApplicationContext reactContext) {
|
|
103
163
|
super(reactContext);
|
|
104
164
|
this.reactContext = reactContext;
|
|
@@ -334,10 +394,23 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
334
394
|
return;
|
|
335
395
|
}
|
|
336
396
|
|
|
337
|
-
//
|
|
338
|
-
String
|
|
397
|
+
// Check if this is a virtual UID that needs conversion
|
|
398
|
+
String realClientId = deviceId;
|
|
399
|
+
if (isVirtualId(deviceId)) {
|
|
400
|
+
Log.d(TAG, "Device ID " + deviceId + " looks like a virtual UID, converting...");
|
|
401
|
+
String[] conversionResult = convertVirtualUid(deviceId);
|
|
402
|
+
if (conversionResult != null && conversionResult[0] != null) {
|
|
403
|
+
realClientId = conversionResult[0];
|
|
404
|
+
Log.d(TAG, "Using converted client ID: " + realClientId);
|
|
405
|
+
} else {
|
|
406
|
+
Log.w(TAG, "Virtual UID conversion failed, trying with original ID");
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Call JNIApi.create(did, serverParam) with real client ID
|
|
411
|
+
String serviceParam = getServiceParam(realClientId); // Use real client ID prefix
|
|
339
412
|
Method createMethod = jniApiClass.getMethod("create", String.class, String.class);
|
|
340
|
-
Object result = createMethod.invoke(null,
|
|
413
|
+
Object result = createMethod.invoke(null, realClientId, serviceParam);
|
|
341
414
|
long sdkClientPtr = (Long) result;
|
|
342
415
|
|
|
343
416
|
Log.d(TAG, "JNIApi.create result: " + sdkClientPtr);
|
|
@@ -353,10 +426,11 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
353
426
|
|
|
354
427
|
ClientInfo clientInfo = new ClientInfo();
|
|
355
428
|
clientInfo.deviceId = deviceId;
|
|
429
|
+
clientInfo.realClientId = realClientId; // Store the converted ID
|
|
356
430
|
clientInfo.sdkClientPtr = sdkClientPtr;
|
|
357
431
|
clients.put(ourClientPtr, clientInfo);
|
|
358
432
|
|
|
359
|
-
Log.d(TAG, "Created client: ourPtr=" + ourClientPtr + ", sdkPtr=" + sdkClientPtr);
|
|
433
|
+
Log.d(TAG, "Created client: ourPtr=" + ourClientPtr + ", sdkPtr=" + sdkClientPtr + ", realId=" + realClientId);
|
|
360
434
|
promise.resolve(ourClientPtr);
|
|
361
435
|
} catch (Exception e) {
|
|
362
436
|
Log.e(TAG, "clientCreate failed", e);
|
|
@@ -392,19 +466,25 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
392
466
|
params.putInt("state", 1); // CONNECTING
|
|
393
467
|
sendEvent("onConnectionStateChanged", params);
|
|
394
468
|
|
|
469
|
+
// Use realClientId for service param lookup (it has the correct prefix like VSTN)
|
|
470
|
+
String realId = clientInfo.realClientId != null ? clientInfo.realClientId : clientInfo.deviceId;
|
|
395
471
|
String param = (serverParam != null && !serverParam.isEmpty())
|
|
396
472
|
? serverParam
|
|
397
|
-
: getServiceParam(
|
|
473
|
+
: getServiceParam(realId);
|
|
474
|
+
|
|
475
|
+
// Default connectType to 126 (from V1 app) if not specified
|
|
476
|
+
// connectType 126 = P2P/Relay combination that works reliably
|
|
477
|
+
int actualConnectType = (connectType <= 0) ? 126 : connectType;
|
|
398
478
|
|
|
399
479
|
// Call JNIApi.connect(sdkClientPtr, timeout, serverParam, connectType)
|
|
400
480
|
// Signature: connect([long, int, class java.lang.String, int])
|
|
401
481
|
Method connectMethod = jniApiClass.getMethod("connect",
|
|
402
482
|
long.class, int.class, String.class, int.class);
|
|
403
483
|
|
|
404
|
-
Log.d(TAG, "Calling JNIApi.connect(" + clientInfo.sdkClientPtr + ", 15, " + param + ", " +
|
|
484
|
+
Log.d(TAG, "Calling JNIApi.connect(" + clientInfo.sdkClientPtr + ", 15, " + param + ", " + actualConnectType + ")");
|
|
405
485
|
|
|
406
486
|
try {
|
|
407
|
-
connectMethod.invoke(null, clientInfo.sdkClientPtr, 15, param,
|
|
487
|
+
connectMethod.invoke(null, clientInfo.sdkClientPtr, 15, param, actualConnectType);
|
|
408
488
|
Log.d(TAG, "JNIApi.connect returned normally");
|
|
409
489
|
} catch (java.lang.reflect.InvocationTargetException ite) {
|
|
410
490
|
Log.e(TAG, "JNIApi.connect threw exception: " + ite.getCause(), ite.getCause());
|
|
@@ -459,7 +539,17 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
459
539
|
long.class, String.class, String.class);
|
|
460
540
|
|
|
461
541
|
Log.d(TAG, "Calling JNIApi.login(" + clientInfo.sdkClientPtr + ", " + username + ", ***)");
|
|
462
|
-
|
|
542
|
+
|
|
543
|
+
try {
|
|
544
|
+
loginMethod.invoke(null, clientInfo.sdkClientPtr, username, password);
|
|
545
|
+
Log.d(TAG, "JNIApi.login returned normally");
|
|
546
|
+
} catch (java.lang.reflect.InvocationTargetException ite) {
|
|
547
|
+
Log.e(TAG, "JNIApi.login threw exception: " + ite.getCause(), ite.getCause());
|
|
548
|
+
throw ite;
|
|
549
|
+
} catch (Throwable t) {
|
|
550
|
+
Log.e(TAG, "JNIApi.login crashed: " + t.getMessage(), t);
|
|
551
|
+
throw t;
|
|
552
|
+
}
|
|
463
553
|
|
|
464
554
|
clientInfo.isLoggedIn = true;
|
|
465
555
|
Log.d(TAG, "JNIApi.login called successfully");
|
|
@@ -614,25 +704,38 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
614
704
|
*/
|
|
615
705
|
@ReactMethod
|
|
616
706
|
public void clientCheckMode(int clientPtr, Promise promise) {
|
|
707
|
+
Log.d(TAG, "clientCheckMode called for: " + clientPtr);
|
|
617
708
|
try {
|
|
618
709
|
ClientInfo clientInfo = clients.get(clientPtr);
|
|
619
710
|
|
|
620
711
|
int mode = 0;
|
|
621
|
-
|
|
712
|
+
// Note: sdkClientPtr can be negative (unsigned to signed cast) - only check != 0
|
|
713
|
+
if (clientInfo != null && jniApiClass != null && clientInfo.sdkClientPtr != 0) {
|
|
622
714
|
try {
|
|
623
715
|
Method checkModeMethod = jniApiClass.getMethod("checkMode", long.class);
|
|
624
716
|
Object result = checkModeMethod.invoke(null, clientInfo.sdkClientPtr);
|
|
625
717
|
mode = (Integer) result;
|
|
626
|
-
Log.d(TAG, "JNIApi.checkMode result: " + mode);
|
|
718
|
+
Log.d(TAG, "JNIApi.checkMode result: " + mode + " (0=none, 1=P2P, 2=relay, 3=sock)");
|
|
627
719
|
} catch (Exception e) {
|
|
628
|
-
Log.e(TAG, "checkMode failed", e);
|
|
720
|
+
Log.e(TAG, "checkMode JNI call failed", e);
|
|
629
721
|
}
|
|
722
|
+
} else {
|
|
723
|
+
Log.w(TAG, "checkMode skipped: clientInfo=" + clientInfo +
|
|
724
|
+
", jniApiClass=" + (jniApiClass != null) +
|
|
725
|
+
", sdkPtr=" + (clientInfo != null ? clientInfo.sdkClientPtr : "null"));
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// Mode > 0 means connected (1=P2P, 2=Relay, 3=Socket)
|
|
729
|
+
boolean connected = mode > 0;
|
|
730
|
+
if (connected && clientInfo != null) {
|
|
731
|
+
clientInfo.isConnected = true;
|
|
630
732
|
}
|
|
631
733
|
|
|
632
734
|
WritableMap result = Arguments.createMap();
|
|
633
|
-
result.putBoolean("success",
|
|
735
|
+
result.putBoolean("success", connected);
|
|
634
736
|
result.putInt("mode", mode);
|
|
635
737
|
result.putDouble("sessionHandle", clientInfo != null ? clientInfo.sdkClientPtr : -1);
|
|
738
|
+
Log.d(TAG, "clientCheckMode returning: success=" + connected + ", mode=" + mode);
|
|
636
739
|
promise.resolve(result);
|
|
637
740
|
} catch (Exception e) {
|
|
638
741
|
Log.e(TAG, "clientCheckMode failed", e);
|
|
@@ -654,7 +757,7 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
654
757
|
@ReactMethod
|
|
655
758
|
public void getSdkVersion(Promise promise) {
|
|
656
759
|
WritableMap result = Arguments.createMap();
|
|
657
|
-
result.putString("version", "1.0.
|
|
760
|
+
result.putString("version", "1.0.17");
|
|
658
761
|
result.putBoolean("nativeLoaded", isNativeLibraryLoaded);
|
|
659
762
|
result.putString("nativeLib", "OKSMARTPPCS");
|
|
660
763
|
result.putBoolean("p2pInitialized", isP2PInitialized);
|