@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
- long sdkClientPtr = 0; // Actual SDK client pointer (long)
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
- // Call JNIApi.create(did, serverParam)
338
- String serviceParam = getServiceParam(deviceId);
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, deviceId, serviceParam);
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(clientInfo.deviceId);
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 + ", " + connectType + ")");
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, connectType);
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
- if (clientInfo != null && jniApiClass != null && clientInfo.sdkClientPtr > 0) {
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", clientInfo != null && clientInfo.isConnected);
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.15");
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bits-innovate/react-native-vstarcam",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "description": "React Native bridge for VStarCam P2P SDK",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",