@bits-innovate/react-native-vstarcam 1.0.15 → 1.0.16
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());
|
|
@@ -614,25 +694,38 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
614
694
|
*/
|
|
615
695
|
@ReactMethod
|
|
616
696
|
public void clientCheckMode(int clientPtr, Promise promise) {
|
|
697
|
+
Log.d(TAG, "clientCheckMode called for: " + clientPtr);
|
|
617
698
|
try {
|
|
618
699
|
ClientInfo clientInfo = clients.get(clientPtr);
|
|
619
700
|
|
|
620
701
|
int mode = 0;
|
|
621
|
-
|
|
702
|
+
// Note: sdkClientPtr can be negative (unsigned to signed cast) - only check != 0
|
|
703
|
+
if (clientInfo != null && jniApiClass != null && clientInfo.sdkClientPtr != 0) {
|
|
622
704
|
try {
|
|
623
705
|
Method checkModeMethod = jniApiClass.getMethod("checkMode", long.class);
|
|
624
706
|
Object result = checkModeMethod.invoke(null, clientInfo.sdkClientPtr);
|
|
625
707
|
mode = (Integer) result;
|
|
626
|
-
Log.d(TAG, "JNIApi.checkMode result: " + mode);
|
|
708
|
+
Log.d(TAG, "JNIApi.checkMode result: " + mode + " (0=none, 1=P2P, 2=relay, 3=sock)");
|
|
627
709
|
} catch (Exception e) {
|
|
628
|
-
Log.e(TAG, "checkMode failed", e);
|
|
710
|
+
Log.e(TAG, "checkMode JNI call failed", e);
|
|
629
711
|
}
|
|
712
|
+
} else {
|
|
713
|
+
Log.w(TAG, "checkMode skipped: clientInfo=" + clientInfo +
|
|
714
|
+
", jniApiClass=" + (jniApiClass != null) +
|
|
715
|
+
", sdkPtr=" + (clientInfo != null ? clientInfo.sdkClientPtr : "null"));
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// Mode > 0 means connected (1=P2P, 2=Relay, 3=Socket)
|
|
719
|
+
boolean connected = mode > 0;
|
|
720
|
+
if (connected && clientInfo != null) {
|
|
721
|
+
clientInfo.isConnected = true;
|
|
630
722
|
}
|
|
631
723
|
|
|
632
724
|
WritableMap result = Arguments.createMap();
|
|
633
|
-
result.putBoolean("success",
|
|
725
|
+
result.putBoolean("success", connected);
|
|
634
726
|
result.putInt("mode", mode);
|
|
635
727
|
result.putDouble("sessionHandle", clientInfo != null ? clientInfo.sdkClientPtr : -1);
|
|
728
|
+
Log.d(TAG, "clientCheckMode returning: success=" + connected + ", mode=" + mode);
|
|
636
729
|
promise.resolve(result);
|
|
637
730
|
} catch (Exception e) {
|
|
638
731
|
Log.e(TAG, "clientCheckMode failed", e);
|
|
@@ -654,7 +747,7 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
654
747
|
@ReactMethod
|
|
655
748
|
public void getSdkVersion(Promise promise) {
|
|
656
749
|
WritableMap result = Arguments.createMap();
|
|
657
|
-
result.putString("version", "1.0.
|
|
750
|
+
result.putString("version", "1.0.16");
|
|
658
751
|
result.putBoolean("nativeLoaded", isNativeLibraryLoaded);
|
|
659
752
|
result.putString("nativeLib", "OKSMARTPPCS");
|
|
660
753
|
result.putBoolean("p2pInitialized", isP2PInitialized);
|