@bits-innovate/react-native-vstarcam 1.0.41 → 1.0.43
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.
|
@@ -11,7 +11,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
|
|
11
11
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
12
12
|
import com.facebook.react.bridge.ReactMethod;
|
|
13
13
|
import com.facebook.react.bridge.WritableMap;
|
|
14
|
-
import com.facebook.react.module.annotations.ReactModule;
|
|
15
14
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
16
15
|
|
|
17
16
|
import java.io.BufferedReader;
|
|
@@ -35,22 +34,22 @@ import org.json.JSONObject;
|
|
|
35
34
|
*
|
|
36
35
|
* Implements P2P camera connectivity using the VStarCam SDK.
|
|
37
36
|
* Uses JNI calls to the native OKSMARTPPCS library via JNIApi class.
|
|
37
|
+
*
|
|
38
|
+
* JNI API Methods (discovered via reflection):
|
|
39
|
+
* - create(String did, String serverParam) -> long clientPtr
|
|
40
|
+
* - connect(long clientPtr, int timeout, String serverParam, int connectType)
|
|
41
|
+
* - login(long clientPtr, String username, String password)
|
|
42
|
+
* - disconnect(long clientPtr)
|
|
43
|
+
* - destroy(long clientPtr)
|
|
44
|
+
* - writeCgi(long clientPtr, String cgi, int timeout)
|
|
45
|
+
* - init(ClientStateListener, ClientCommandListener, ClientReleaseListener)
|
|
38
46
|
*/
|
|
39
|
-
@ReactModule(name = "VStarCam")
|
|
40
47
|
public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
41
48
|
private static final String TAG = "VStarCamModule";
|
|
42
|
-
|
|
49
|
+
private static final String MODULE_NAME = "VStarCam";
|
|
43
50
|
|
|
44
51
|
// Set to true for verbose logging during development
|
|
45
|
-
private static final boolean DEBUG_LOGGING =
|
|
46
|
-
|
|
47
|
-
// Counter for unique internal client IDs
|
|
48
|
-
private static final java.util.concurrent.atomic.AtomicInteger nextClientPtr = new java.util.concurrent.atomic.AtomicInteger(1000);
|
|
49
|
-
|
|
50
|
-
// Static proxy references to prevent GC.
|
|
51
|
-
private static Object stateListenerProxy;
|
|
52
|
-
private static Object commandListenerProxy;
|
|
53
|
-
private static Object releaseListenerProxy;
|
|
52
|
+
private static final boolean DEBUG_LOGGING = false;
|
|
54
53
|
|
|
55
54
|
// Helper for conditional debug logging
|
|
56
55
|
private static void logDebug(String message) {
|
|
@@ -78,8 +77,6 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
78
77
|
put("VSKM", "EIHGFNBAKMIIGLJEEAHKFEEJHLNBHCNIGFFDBLCMAKJNLELPDDAGCNOOGILMJFLJAOMKLADEOEMJAPCDJCNPJF:veepai2024");
|
|
79
78
|
put("VSLL", "EIHGFOBBKKIOGNJKENHHFKEEGMNOHLMNHBFKBBDOAHJBLMKIDLAJCAPIGDLBJGLKAOMILNDJOJMGAHCLJHNMJG:veepai2024");
|
|
80
79
|
put("ACAE", "EEGDFHBLKGJIGEJLEKGOFMEDHAMHHJNAGGFABMCOBGJOLHLJDFAFCPPHGILKIKLMANNHKEDKOINIBNCPJOMK:vstarcam2018"); // Try VSTH params
|
|
81
|
-
put("ACDG", "EEGDFHBLKGJIGEJLEKGOFMEDHAMHHJNAGGFABMCOBGJOLHLJDFAFCPPHGILKIKLMANNHKEDKOINIBNCPJOMK:vstarcam2018"); // Same as ACAE/VSTH
|
|
82
|
-
put("ACAQ", "EEGDFHBLKGJIGEJLEKGOFMEDHAMHHJNAGGFABMCOBGJOLHLJDFAFCPPHGILKIKLMANNHKEDKOINIBNCPJOMK:vstarcam2018"); // Same as ACAE/VSTH
|
|
83
80
|
// Fallback for unknown prefixes
|
|
84
81
|
put("DEFAULT", "EBGBEMBMKGJMGAJPEIGIFKEGHBMCHMNFGKEGBFCBBMJELILDCJADCIOLHHLLJBKEAMMBLCDGONMDBJCJJPNFJP");
|
|
85
82
|
}};
|
|
@@ -99,7 +96,56 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
99
96
|
return param;
|
|
100
97
|
}
|
|
101
98
|
|
|
102
|
-
|
|
99
|
+
// Pattern to detect virtual UIDs (like ACAE0001151GWYQ)
|
|
100
|
+
// Virtual UIDs: start with letters, have 7+ digits, end with letters
|
|
101
|
+
private static final Pattern VIRTUAL_UID_PATTERN = Pattern.compile("^[a-zA-Z]{1,}\\d{7,}.*[a-zA-Z]$");
|
|
102
|
+
|
|
103
|
+
// Check if a device ID is a virtual UID that needs conversion
|
|
104
|
+
private static boolean isVirtualId(String deviceId) {
|
|
105
|
+
if (deviceId == null || deviceId.length() < 10) return false;
|
|
106
|
+
return VIRTUAL_UID_PATTERN.matcher(deviceId).matches();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Convert virtual UID to real client ID using VStarCam API
|
|
110
|
+
// Returns: {uid, supplier, cluster} or null on failure
|
|
111
|
+
private String[] convertVirtualUid(String virtualUid) {
|
|
112
|
+
try {
|
|
113
|
+
URL url = new URL("https://vuid.eye4.cn?vuid=" + virtualUid);
|
|
114
|
+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
|
115
|
+
conn.setRequestMethod("GET");
|
|
116
|
+
conn.setConnectTimeout(10000);
|
|
117
|
+
conn.setReadTimeout(10000);
|
|
118
|
+
conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
|
|
119
|
+
|
|
120
|
+
int responseCode = conn.getResponseCode();
|
|
121
|
+
if (responseCode == 200) {
|
|
122
|
+
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
|
123
|
+
StringBuilder response = new StringBuilder();
|
|
124
|
+
String line;
|
|
125
|
+
while ((line = reader.readLine()) != null) {
|
|
126
|
+
response.append(line);
|
|
127
|
+
}
|
|
128
|
+
reader.close();
|
|
129
|
+
|
|
130
|
+
JSONObject json = new JSONObject(response.toString());
|
|
131
|
+
String uid = json.optString("uid", null);
|
|
132
|
+
String supplier = json.optString("supplier", "");
|
|
133
|
+
String cluster = json.optString("cluster", "");
|
|
134
|
+
|
|
135
|
+
if (uid != null && !uid.isEmpty()) {
|
|
136
|
+
Log.d(TAG, "Converted virtual UID " + virtualUid + " -> real UID: " + uid + " (supplier: " + supplier + ", cluster: " + cluster + ")");
|
|
137
|
+
return new String[]{uid, supplier, cluster};
|
|
138
|
+
}
|
|
139
|
+
} else {
|
|
140
|
+
Log.e(TAG, "Virtual UID conversion failed, HTTP " + responseCode);
|
|
141
|
+
}
|
|
142
|
+
conn.disconnect();
|
|
143
|
+
} catch (Exception e) {
|
|
144
|
+
Log.e(TAG, "Failed to convert virtual UID: " + e.getMessage(), e);
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
|
|
103
149
|
private final ReactApplicationContext reactContext;
|
|
104
150
|
private final ExecutorService executor;
|
|
105
151
|
|
|
@@ -116,7 +162,8 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
116
162
|
private Class<?> releaseListenerClass = null;
|
|
117
163
|
|
|
118
164
|
private static class ClientInfo {
|
|
119
|
-
String deviceId; // Original device ID
|
|
165
|
+
String deviceId; // Original device ID (can be virtual UID)
|
|
166
|
+
String realClientId; // Converted client ID (for JNI calls)
|
|
120
167
|
long sdkClientPtr = 0; // Actual SDK client pointer (long)
|
|
121
168
|
boolean isConnected = false;
|
|
122
169
|
boolean isLoggedIn = false;
|
|
@@ -158,11 +205,25 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
158
205
|
Log.d(TAG, "JNIApi class found: " + jniApiClass.getName());
|
|
159
206
|
|
|
160
207
|
// Load listener interfaces
|
|
161
|
-
stateListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientStateListener"
|
|
162
|
-
commandListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientCommandListener"
|
|
163
|
-
releaseListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientReleaseListener"
|
|
208
|
+
stateListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientStateListener");
|
|
209
|
+
commandListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientCommandListener");
|
|
210
|
+
releaseListenerClass = Class.forName("com.vstarcam.app_p2p_api.ClientReleaseListener");
|
|
164
211
|
Log.d(TAG, "Listener interfaces loaded");
|
|
165
212
|
|
|
213
|
+
// Log all methods on each listener for debugging
|
|
214
|
+
Log.d(TAG, "ClientStateListener methods:");
|
|
215
|
+
for (Method m : stateListenerClass.getDeclaredMethods()) {
|
|
216
|
+
Log.d(TAG, " -> " + m.getName() + "(" + java.util.Arrays.toString(m.getParameterTypes()) + ")");
|
|
217
|
+
}
|
|
218
|
+
Log.d(TAG, "ClientCommandListener methods:");
|
|
219
|
+
for (Method m : commandListenerClass.getDeclaredMethods()) {
|
|
220
|
+
Log.d(TAG, " -> " + m.getName() + "(" + java.util.Arrays.toString(m.getParameterTypes()) + ")");
|
|
221
|
+
}
|
|
222
|
+
Log.d(TAG, "ClientReleaseListener methods:");
|
|
223
|
+
for (Method m : releaseListenerClass.getDeclaredMethods()) {
|
|
224
|
+
Log.d(TAG, " -> " + m.getName() + "(" + java.util.Arrays.toString(m.getParameterTypes()) + ")");
|
|
225
|
+
}
|
|
226
|
+
|
|
166
227
|
// Initialize P2P system with listeners
|
|
167
228
|
initializeP2P();
|
|
168
229
|
} catch (ClassNotFoundException e) {
|
|
@@ -182,24 +243,15 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
182
243
|
|
|
183
244
|
try {
|
|
184
245
|
// Create dynamic proxy for ClientStateListener
|
|
185
|
-
|
|
246
|
+
Object stateListener = Proxy.newProxyInstance(
|
|
186
247
|
stateListenerClass.getClassLoader(),
|
|
187
248
|
new Class<?>[] { stateListenerClass },
|
|
188
249
|
new InvocationHandler() {
|
|
189
250
|
@Override
|
|
190
251
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
191
252
|
try {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// Handle standard Object methods
|
|
195
|
-
if (method.getDeclaringClass() == Object.class) {
|
|
196
|
-
if (methodName.equals("equals")) return proxy == args[0];
|
|
197
|
-
if (methodName.equals("hashCode")) return System.identityHashCode(proxy);
|
|
198
|
-
if (methodName.equals("toString")) return proxy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(proxy));
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
Log.d(TAG, "ClientStateListener." + methodName + " called");
|
|
202
|
-
if (methodName.equals("stateListener")) {
|
|
253
|
+
Log.d(TAG, "ClientStateListener." + method.getName() + " called with " + (args != null ? args.length : 0) + " args");
|
|
254
|
+
if (method.getName().equals("stateListener")) {
|
|
203
255
|
// args: long clientPtr, int state
|
|
204
256
|
final long clientPtr = (Long) args[0];
|
|
205
257
|
final int state = (Integer) args[1];
|
|
@@ -224,34 +276,26 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
224
276
|
);
|
|
225
277
|
|
|
226
278
|
// Create dynamic proxy for ClientCommandListener
|
|
227
|
-
|
|
279
|
+
Object commandListener = Proxy.newProxyInstance(
|
|
228
280
|
commandListenerClass.getClassLoader(),
|
|
229
281
|
new Class<?>[] { commandListenerClass },
|
|
230
282
|
new InvocationHandler() {
|
|
231
283
|
@Override
|
|
232
284
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
233
285
|
try {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (methodName.equals("equals")) return proxy == args[0];
|
|
239
|
-
if (methodName.equals("hashCode")) return System.identityHashCode(proxy);
|
|
240
|
-
if (methodName.equals("toString")) return proxy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(proxy));
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
Log.d(TAG, "ClientCommandListener." + methodName + " called");
|
|
244
|
-
if (methodName.equals("commandListener")) {
|
|
245
|
-
final long sdkPtr = (Long) args[0];
|
|
286
|
+
Log.d(TAG, "ClientCommandListener." + method.getName() + " called with " + (args != null ? args.length : 0) + " args");
|
|
287
|
+
if (method.getName().equals("commandListener")) {
|
|
288
|
+
// args: long clientPtr, byte[] data, int length (from interface)
|
|
289
|
+
final long clientPtr = (Long) args[0];
|
|
246
290
|
final byte[] data = (byte[]) args[1];
|
|
247
291
|
final int length = (Integer) args[2];
|
|
248
|
-
Log.d(TAG, "Command callback:
|
|
292
|
+
Log.d(TAG, "Command callback: clientPtr=" + clientPtr + ", dataLen=" + (data != null ? data.length : 0));
|
|
249
293
|
|
|
250
294
|
if (reactContext != null) {
|
|
251
295
|
reactContext.runOnUiQueueThread(new Runnable() {
|
|
252
296
|
@Override
|
|
253
297
|
public void run() {
|
|
254
|
-
handleCommandReceive(
|
|
298
|
+
handleCommandReceive(clientPtr, 0, data);
|
|
255
299
|
}
|
|
256
300
|
});
|
|
257
301
|
}
|
|
@@ -265,23 +309,14 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
265
309
|
);
|
|
266
310
|
|
|
267
311
|
// Create dynamic proxy for ClientReleaseListener
|
|
268
|
-
|
|
312
|
+
Object releaseListener = Proxy.newProxyInstance(
|
|
269
313
|
releaseListenerClass.getClassLoader(),
|
|
270
314
|
new Class<?>[] { releaseListenerClass },
|
|
271
315
|
new InvocationHandler() {
|
|
272
316
|
@Override
|
|
273
317
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
274
318
|
try {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
// Handle standard Object methods
|
|
278
|
-
if (method.getDeclaringClass() == Object.class) {
|
|
279
|
-
if (methodName.equals("equals")) return proxy == args[0];
|
|
280
|
-
if (methodName.equals("hashCode")) return System.identityHashCode(proxy);
|
|
281
|
-
if (methodName.equals("toString")) return proxy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(proxy));
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
Log.d(TAG, "ClientReleaseListener." + methodName + " called");
|
|
319
|
+
Log.d(TAG, "ClientReleaseListener." + method.getName() + " called");
|
|
285
320
|
} catch (Exception e) {
|
|
286
321
|
Log.e(TAG, "Error in releaseListener callback", e);
|
|
287
322
|
}
|
|
@@ -293,7 +328,7 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
293
328
|
// Call JNIApi.init(stateListener, commandListener, releaseListener)
|
|
294
329
|
Method initMethod = jniApiClass.getMethod("init",
|
|
295
330
|
stateListenerClass, commandListenerClass, releaseListenerClass);
|
|
296
|
-
initMethod.invoke(null,
|
|
331
|
+
initMethod.invoke(null, stateListener, commandListener, releaseListener);
|
|
297
332
|
|
|
298
333
|
isP2PInitialized = true;
|
|
299
334
|
Log.d(TAG, "P2P system initialized successfully!");
|
|
@@ -383,10 +418,23 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
383
418
|
return;
|
|
384
419
|
}
|
|
385
420
|
|
|
386
|
-
//
|
|
387
|
-
String
|
|
421
|
+
// Check if this is a virtual UID that needs conversion
|
|
422
|
+
String realClientId = deviceId;
|
|
423
|
+
if (isVirtualId(deviceId)) {
|
|
424
|
+
Log.d(TAG, "Device ID " + deviceId + " looks like a virtual UID, converting...");
|
|
425
|
+
String[] conversionResult = convertVirtualUid(deviceId);
|
|
426
|
+
if (conversionResult != null && conversionResult[0] != null) {
|
|
427
|
+
realClientId = conversionResult[0];
|
|
428
|
+
Log.d(TAG, "Using converted client ID: " + realClientId);
|
|
429
|
+
} else {
|
|
430
|
+
Log.w(TAG, "Virtual UID conversion failed, trying with original ID");
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Call JNIApi.create(did, serverParam) with real client ID
|
|
435
|
+
String serviceParam = getServiceParam(realClientId); // Use real client ID prefix
|
|
388
436
|
Method createMethod = jniApiClass.getMethod("create", String.class, String.class);
|
|
389
|
-
Object result = createMethod.invoke(null,
|
|
437
|
+
Object result = createMethod.invoke(null, realClientId, serviceParam);
|
|
390
438
|
long sdkClientPtr = (Long) result;
|
|
391
439
|
|
|
392
440
|
Log.d(TAG, "JNIApi.create result: " + sdkClientPtr);
|
|
@@ -402,10 +450,11 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
402
450
|
|
|
403
451
|
ClientInfo clientInfo = new ClientInfo();
|
|
404
452
|
clientInfo.deviceId = deviceId;
|
|
453
|
+
clientInfo.realClientId = realClientId; // Store the converted ID
|
|
405
454
|
clientInfo.sdkClientPtr = sdkClientPtr;
|
|
406
455
|
clients.put(ourClientPtr, clientInfo);
|
|
407
456
|
|
|
408
|
-
Log.d(TAG, "Created client: ourPtr=" + ourClientPtr + ", sdkPtr=" + sdkClientPtr);
|
|
457
|
+
Log.d(TAG, "Created client: ourPtr=" + ourClientPtr + ", sdkPtr=" + sdkClientPtr + ", realId=" + realClientId);
|
|
409
458
|
promise.resolve(ourClientPtr);
|
|
410
459
|
} catch (Exception e) {
|
|
411
460
|
Log.e(TAG, "clientCreate failed", e);
|
|
@@ -441,10 +490,11 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
441
490
|
params.putInt("state", 1); // CONNECTING
|
|
442
491
|
sendEvent("onConnectionStateChanged", params);
|
|
443
492
|
|
|
444
|
-
//
|
|
493
|
+
// Use realClientId for service param lookup (it has the correct prefix like VSTN)
|
|
494
|
+
String realId = clientInfo.realClientId != null ? clientInfo.realClientId : clientInfo.deviceId;
|
|
445
495
|
String param = (serverParam != null && !serverParam.isEmpty())
|
|
446
496
|
? serverParam
|
|
447
|
-
: getServiceParam(
|
|
497
|
+
: getServiceParam(realId);
|
|
448
498
|
|
|
449
499
|
// Default connectType to 126 (from V1 app) if not specified
|
|
450
500
|
// connectType 126 = P2P/Relay combination that works reliably
|
|
@@ -458,8 +508,8 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
458
508
|
Log.d(TAG, "Calling JNIApi.connect(" + clientInfo.sdkClientPtr + ", 15, " + param + ", " + actualConnectType + ")");
|
|
459
509
|
|
|
460
510
|
try {
|
|
461
|
-
|
|
462
|
-
Log.d(TAG, "JNIApi.connect
|
|
511
|
+
connectMethod.invoke(null, clientInfo.sdkClientPtr, 15, param, actualConnectType);
|
|
512
|
+
Log.d(TAG, "JNIApi.connect returned normally");
|
|
463
513
|
} catch (java.lang.reflect.InvocationTargetException ite) {
|
|
464
514
|
Log.e(TAG, "JNIApi.connect threw exception: " + ite.getCause(), ite.getCause());
|
|
465
515
|
throw ite;
|
|
@@ -512,21 +562,34 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
512
562
|
Method loginMethod = jniApiClass.getMethod("login",
|
|
513
563
|
long.class, String.class, String.class);
|
|
514
564
|
|
|
515
|
-
Log.d(TAG, "Calling JNIApi.login(" + clientInfo.sdkClientPtr + ", " + username + ")");
|
|
565
|
+
Log.d(TAG, "Calling JNIApi.login(" + clientInfo.sdkClientPtr + ", " + username + ", ***)");
|
|
516
566
|
|
|
567
|
+
boolean loginSuccess = false;
|
|
517
568
|
try {
|
|
518
569
|
loginMethod.invoke(null, clientInfo.sdkClientPtr, username, password);
|
|
519
|
-
|
|
520
|
-
|
|
570
|
+
Log.d(TAG, "JNIApi.login returned normally");
|
|
571
|
+
loginSuccess = true;
|
|
572
|
+
} catch (java.lang.reflect.InvocationTargetException ite) {
|
|
573
|
+
Throwable cause = ite.getCause();
|
|
574
|
+
Log.e(TAG, "JNIApi.login threw exception: " + cause, cause);
|
|
575
|
+
// Don't rethrow - return false instead to prevent crash
|
|
576
|
+
promise.resolve(false);
|
|
577
|
+
return;
|
|
578
|
+
} catch (Throwable t) {
|
|
579
|
+
Log.e(TAG, "JNIApi.login crashed: " + t.getMessage(), t);
|
|
580
|
+
// Don't rethrow - return false instead to prevent crash
|
|
521
581
|
promise.resolve(false);
|
|
522
582
|
return;
|
|
523
583
|
}
|
|
524
584
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
585
|
+
if (loginSuccess) {
|
|
586
|
+
clientInfo.isLoggedIn = true;
|
|
587
|
+
clientInfo.username = username;
|
|
588
|
+
clientInfo.password = password;
|
|
589
|
+
}
|
|
528
590
|
|
|
529
|
-
|
|
591
|
+
Log.d(TAG, "JNIApi.login completed with result: " + loginSuccess);
|
|
592
|
+
promise.resolve(loginSuccess);
|
|
530
593
|
} catch (Exception e) {
|
|
531
594
|
Log.e(TAG, "clientLogin failed", e);
|
|
532
595
|
promise.reject("LOGIN_ERROR", e.getMessage());
|
|
@@ -651,42 +714,6 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
|
|
|
651
714
|
});
|
|
652
715
|
}
|
|
653
716
|
|
|
654
|
-
/**
|
|
655
|
-
* Get device information
|
|
656
|
-
*/
|
|
657
|
-
@ReactMethod
|
|
658
|
-
public void clientGetDeviceInfo(int clientPtr, Promise promise) {
|
|
659
|
-
executor.execute(() -> {
|
|
660
|
-
try {
|
|
661
|
-
ClientInfo clientInfo = clients.get(clientPtr);
|
|
662
|
-
if (clientInfo == null) {
|
|
663
|
-
promise.reject("E_CLIENT_NOT_FOUND", "Client not found");
|
|
664
|
-
return;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
WritableMap result = Arguments.createMap();
|
|
668
|
-
result.putString("serialNumber", clientInfo.deviceId);
|
|
669
|
-
result.putString("model", "VStarCam");
|
|
670
|
-
result.putString("firmware", "Unknown");
|
|
671
|
-
result.putString("manufacturer", "VStarCam");
|
|
672
|
-
result.putBoolean("responsive", clientInfo.isConnected);
|
|
673
|
-
|
|
674
|
-
WritableMap features = Arguments.createMap();
|
|
675
|
-
features.putBoolean("ptz", true);
|
|
676
|
-
features.putBoolean("audio", true);
|
|
677
|
-
features.putBoolean("twoWayAudio", true);
|
|
678
|
-
features.putBoolean("nightVision", true);
|
|
679
|
-
features.putBoolean("motionDetection", true);
|
|
680
|
-
features.putBoolean("wifi", true);
|
|
681
|
-
result.putMap("features", features);
|
|
682
|
-
|
|
683
|
-
promise.resolve(result);
|
|
684
|
-
} catch (Exception e) {
|
|
685
|
-
promise.reject("E_GET_INFO_FAILED", e.getMessage());
|
|
686
|
-
}
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
|
-
|
|
690
717
|
/**
|
|
691
718
|
* Start video stream by sending livestream.cgi command
|
|
692
719
|
* Resolution: 1=high, 2=general, 4=low, 100=superHD
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -288,6 +288,14 @@ class VStarCamClient {
|
|
|
288
288
|
return VStarCamModule.clientCheckMode(this.clientPtr);
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Get the current connection state of the client
|
|
293
|
+
*/
|
|
294
|
+
async getState(): Promise<any> {
|
|
295
|
+
if (!this.clientPtr) return { state: 5, isConnected: false };
|
|
296
|
+
return VStarCamModule.clientGetState(this.clientPtr);
|
|
297
|
+
}
|
|
298
|
+
|
|
291
299
|
/**
|
|
292
300
|
* Login to the camera
|
|
293
301
|
* @param username Camera username (default: admin)
|