@ledgerhq/device-transport-kit-react-native-hid 0.0.0-rn-ble-perf-20251009143619 → 0.0.0-rn-hid-issues-20251023075200

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.
@@ -17,11 +17,14 @@ import com.ledger.devicesdk.shared.androidMain.transport.usb.controller.ACTION_U
17
17
  import com.ledger.devicesdk.shared.androidMain.transport.usb.controller.UsbAttachedReceiverController
18
18
  import com.ledger.devicesdk.shared.androidMain.transport.usb.controller.UsbDetachedReceiverController
19
19
  import com.ledger.devicesdk.shared.androidMain.transport.usb.controller.UsbPermissionReceiver
20
+ import com.ledger.devicesdk.shared.api.apdu.SendApduFailureReason
21
+ import com.ledger.devicesdk.shared.api.apdu.SendApduResult
20
22
  import com.ledger.devicesdk.shared.api.discovery.DiscoveryDevice
21
23
  import com.ledger.devicesdk.shared.internal.connection.InternalConnectedDevice
22
24
  import com.ledger.devicesdk.shared.internal.connection.InternalConnectionResult
23
25
  import com.ledger.devicesdk.shared.internal.event.SdkEventDispatcher
24
26
  import com.ledger.devicesdk.shared.internal.service.logger.LoggerService
27
+ import com.ledger.devicesdk.shared.internal.service.logger.buildSimpleDebugLogInfo
25
28
  import com.ledger.devicesdk.shared.internal.transport.TransportEvent
26
29
  import kotlinx.coroutines.CoroutineScope
27
30
  import kotlinx.coroutines.Dispatchers
@@ -34,6 +37,8 @@ import kotlin.random.Random
34
37
  import kotlin.time.Duration
35
38
  import kotlin.time.Duration.Companion.milliseconds
36
39
 
40
+ private val TAG = "TransportHidModule"
41
+
37
42
  class TransportHidModule(
38
43
  private val reactContext: ReactApplicationContext,
39
44
  private val coroutineScope: CoroutineScope
@@ -133,12 +138,18 @@ class TransportHidModule(
133
138
  transport?.stopScan()
134
139
  }
135
140
 
136
- private var discoveryCount = 0
141
+ private var activeScanCount = 0
137
142
 
138
143
  @ReactMethod
139
144
  fun startScan(promise: Promise) {
140
- discoveryCount += 1
141
- if (discoveryCount > 1) {
145
+ loggerService.log(
146
+ buildSimpleDebugLogInfo(TAG, "[startScan] called")
147
+ )
148
+ activeScanCount += 1
149
+ if (activeScanCount > 1) {
150
+ loggerService.log(
151
+ buildSimpleDebugLogInfo(TAG, "[startScan] already scanning")
152
+ )
142
153
  promise.resolve(null)
143
154
  return
144
155
  }
@@ -156,16 +167,34 @@ class TransportHidModule(
156
167
 
157
168
  @ReactMethod
158
169
  fun stopScan(promise: Promise) {
159
- discoveryCount -= 1
160
- if (discoveryCount > 0) {
161
- promise.resolve(null)
162
- return
163
- }
164
- try {
165
- transport!!.stopScan()
166
- promise.resolve(null)
167
- } catch (e: Exception) {
168
- promise.reject(e);
170
+ loggerService.log(
171
+ buildSimpleDebugLogInfo(TAG, "[stopScan] called, activeScanCount=$activeScanCount")
172
+ )
173
+
174
+ when(activeScanCount) {
175
+ 0 -> {
176
+ loggerService.log(buildSimpleDebugLogInfo(TAG, "[stopScan] no active scan"))
177
+ promise.resolve(null)
178
+ }
179
+ 1 -> {
180
+ try {
181
+ transport!!.stopScan()
182
+ promise.resolve(null)
183
+ } catch (e: Exception) {
184
+ promise.reject(e);
185
+ }
186
+ activeScanCount = 0
187
+ }
188
+ else -> {
189
+ loggerService.log(
190
+ buildSimpleDebugLogInfo(
191
+ TAG,
192
+ "[stopScan] still scanning because there are active listeners"
193
+ )
194
+ )
195
+ activeScanCount -= 1
196
+ promise.resolve(null)
197
+ }
169
198
  }
170
199
  }
171
200
 
@@ -217,7 +246,9 @@ class TransportHidModule(
217
246
  try {
218
247
  val device = connectedDevices.firstOrNull() { it.id == sessionId }
219
248
  if (device == null) {
220
- promise.reject(Exception("[TransportHidModule][sendApdu] Device not found"))
249
+ promise.resolve(
250
+ SendApduResult.Failure(SendApduFailureReason.DeviceNotFound).toWritableMap()
251
+ )
221
252
  return
222
253
  }
223
254
  coroutineScope.launch {
@@ -45,6 +45,8 @@ import kotlinx.coroutines.launch
45
45
  import kotlin.time.Duration
46
46
  import kotlin.time.Duration.Companion.seconds
47
47
 
48
+ private val TAG = "DefaultAndroidUsbTransport"
49
+
48
50
  internal class DefaultAndroidUsbTransport(
49
51
  private val application: Application,
50
52
  private val usbManager: UsbManager,
@@ -67,22 +69,16 @@ internal class DefaultAndroidUsbTransport(
67
69
  private var discoveryJob: Job? = null
68
70
 
69
71
  override fun startScan(): Flow<List<DiscoveryDevice>> {
72
+ loggerService.log(buildSimpleDebugLogInfo(TAG, "[startScan] called"))
70
73
  val scanStateFlow = MutableStateFlow<List<DiscoveryDevice>>(emptyList())
71
74
  discoveryJob?.cancel()
72
75
  discoveryJob =
73
76
  scope.launch {
74
77
  while (isActive) {
75
- val usbDevices = usbManager.deviceList.values.toList()
76
- val devices =
77
- usbDevices
78
- .filter { device ->
79
- usbConnections.filter {
80
- device == it.value.getApduSender().dependencies.usbDevice
81
- }.isEmpty()
82
- }.toUsbDevices()
83
-
84
- scanStateFlow.value = devices.toScannedDevices()
85
-
78
+ loggerService.log(buildSimpleDebugLogInfo(TAG, "[startScan] isActive loop"))
79
+ val usbDevices = usbManager.deviceList.values.toList().toUsbDevices()
80
+ scanStateFlow.value = usbDevices.toScannedDevices()
81
+ loggerService.log(buildSimpleDebugLogInfo(TAG, "[startScan] scannedDevices=${scanStateFlow.value}"))
86
82
  delay(scanDelay)
87
83
  }
88
84
  }
@@ -90,6 +86,7 @@ internal class DefaultAndroidUsbTransport(
90
86
  }
91
87
 
92
88
  override fun stopScan() {
89
+ loggerService.log(buildSimpleDebugLogInfo(TAG, "[stopScan] called"))
93
90
  discoveryJob?.cancel()
94
91
  discoveryJob = null
95
92
  }
@@ -294,6 +291,27 @@ internal class DefaultAndroidUsbTransport(
294
291
  return if (usbDevice == null || ledgerUsbDevice == null) {
295
292
  InternalConnectionResult.ConnectionError(error = InternalConnectionResult.Failure.DeviceNotFound)
296
293
  } else {
294
+
295
+ val existingConnection = usbConnections.firstNotNullOfOrNull {
296
+ if (it.value.getApduSender().dependencies.usbDevice == usbDevice) it.value
297
+ else if (it.key == generateSessionId(usbDevice)) it.value
298
+ else null
299
+ }
300
+
301
+ if (existingConnection != null) {
302
+ val connectedDevice =
303
+ InternalConnectedDevice(
304
+ existingConnection.sessionId,
305
+ discoveryDevice.name,
306
+ discoveryDevice.ledgerDevice,
307
+ discoveryDevice.connectivityType,
308
+ sendApduFn = { apdu: ByteArray, triggersDisconnection: Boolean, abortTimeoutDuration: Duration ->
309
+ existingConnection.requestSendApdu(apdu, triggersDisconnection, abortTimeoutDuration)
310
+ }
311
+ )
312
+ return InternalConnectionResult.Connected(device = connectedDevice, sessionId = existingConnection.sessionId)
313
+ }
314
+
297
315
  val permissionResult = checkOrRequestPermission(usbDevice)
298
316
  if (permissionResult is PermissionResult.Denied) {
299
317
  return permissionResult.connectionError
package/lib/cjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var d=(o,r)=>{for(var T in r)a(o,T,{get:r[T],enumerable:!0})},f=(o,r,T,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of I(r))!R.call(o,t)&&t!==T&&a(o,t,{get:()=>r[t],enumerable:!(e=p(r,t))||e.enumerable});return o};var s=o=>f(a({},"__esModule",{value:!0}),o);var N={};d(N,{RNHidTransportFactory:()=>i.RNHidTransportFactory,rnHidTransportIdentifier:()=>n.TRANSPORT_IDENTIFIER});module.exports=s(N);var i=require("./api/RNHidTransportFactory"),n=require("./api/transport/rnHidTransportIdentifier");0&&(module.exports={RNHidTransportFactory,rnHidTransportIdentifier});
1
+ "use strict";var p=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var I=(o,r)=>{for(var t in r)p(o,t,{get:r[t],enumerable:!0})},R=(o,r,t,d)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of f(r))!s.call(o,n)&&n!==t&&p(o,n,{get:()=>r[n],enumerable:!(d=i(r,n))||d.enumerable});return o};var m=o=>R(p({},"__esModule",{value:!0}),o);var x={};I(x,{HidTransportSendApduUnknownError:()=>T.HidTransportSendApduUnknownError,RNHidTransportFactory:()=>e.RNHidTransportFactory,rnHidTransportIdentifier:()=>a.TRANSPORT_IDENTIFIER});module.exports=m(x);var e=require("./api/RNHidTransportFactory"),T=require("./api/transport/Errors"),a=require("./api/transport/rnHidTransportIdentifier");0&&(module.exports={HidTransportSendApduUnknownError,RNHidTransportFactory,rnHidTransportIdentifier});
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["export { RNHidTransportFactory } from \"@api/RNHidTransportFactory\";\nexport { TRANSPORT_IDENTIFIER as rnHidTransportIdentifier } from \"@api/transport/rnHidTransportIdentifier\";\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,wHAAAE,EAAAF,GAAA,IAAAG,EAAsC,sCACtCC,EAAiE",
6
- "names": ["index_exports", "__export", "__toCommonJS", "import_RNHidTransportFactory", "import_rnHidTransportIdentifier"]
4
+ "sourcesContent": ["export { RNHidTransportFactory } from \"@api/RNHidTransportFactory\";\nexport { HidTransportSendApduUnknownError } from \"@api/transport/Errors\";\nexport { TRANSPORT_IDENTIFIER as rnHidTransportIdentifier } from \"@api/transport/rnHidTransportIdentifier\";\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gMAAAE,EAAAF,GAAA,IAAAG,EAAsC,sCACtCC,EAAiD,iCACjDC,EAAiE",
6
+ "names": ["index_exports", "__export", "__toCommonJS", "import_RNHidTransportFactory", "import_Errors", "import_rnHidTransportIdentifier"]
7
7
  }
package/lib/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{RNHidTransportFactory as t}from"./api/RNHidTransportFactory";import{TRANSPORT_IDENTIFIER as a}from"./api/transport/rnHidTransportIdentifier";export{t as RNHidTransportFactory,a as rnHidTransportIdentifier};
1
+ import{RNHidTransportFactory as n}from"./api/RNHidTransportFactory";import{HidTransportSendApduUnknownError as p}from"./api/transport/Errors";import{TRANSPORT_IDENTIFIER as e}from"./api/transport/rnHidTransportIdentifier";export{p as HidTransportSendApduUnknownError,n as RNHidTransportFactory,e as rnHidTransportIdentifier};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["export { RNHidTransportFactory } from \"@api/RNHidTransportFactory\";\nexport { TRANSPORT_IDENTIFIER as rnHidTransportIdentifier } from \"@api/transport/rnHidTransportIdentifier\";\n"],
5
- "mappings": "AAAA,OAAS,yBAAAA,MAA6B,6BACtC,OAAiC,wBAAxBC,MAAwD",
6
- "names": ["RNHidTransportFactory", "TRANSPORT_IDENTIFIER"]
4
+ "sourcesContent": ["export { RNHidTransportFactory } from \"@api/RNHidTransportFactory\";\nexport { HidTransportSendApduUnknownError } from \"@api/transport/Errors\";\nexport { TRANSPORT_IDENTIFIER as rnHidTransportIdentifier } from \"@api/transport/rnHidTransportIdentifier\";\n"],
5
+ "mappings": "AAAA,OAAS,yBAAAA,MAA6B,6BACtC,OAAS,oCAAAC,MAAwC,wBACjD,OAAiC,wBAAxBC,MAAwD",
6
+ "names": ["RNHidTransportFactory", "HidTransportSendApduUnknownError", "TRANSPORT_IDENTIFIER"]
7
7
  }
@@ -1,3 +1,4 @@
1
1
  export { RNHidTransportFactory } from "./api/RNHidTransportFactory";
2
+ export { HidTransportSendApduUnknownError } from "./api/transport/Errors";
2
3
  export { TRANSPORT_IDENTIFIER as rnHidTransportIdentifier } from "./api/transport/rnHidTransportIdentifier";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,oBAAoB,IAAI,wBAAwB,EAAE,MAAM,yCAAyC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,oBAAoB,IAAI,wBAAwB,EAAE,MAAM,yCAAyC,CAAC"}