@@ -47,8 +47,8 @@ export class WebHidDeviceConnection implements DeviceConnection {
47
47
private waitingForReconnection = false ;
48
48
/** Timeout to wait for the device to reconnect */
49
49
private lostConnectionTimeout : Timer | null = null ;
50
- /** Time since disconnection */
51
- private timeSinceDisconnection : Maybe < number > = Nothing ;
50
+ /** Timestamp when the device was reconnected */
51
+ private timeOfReconnection : Maybe < number > = Nothing ;
52
52
/** Flag to indicate if the connection is terminated */
53
53
private terminated = false ;
54
54
@@ -133,6 +133,9 @@ export class WebHidDeviceConnection implements DeviceConnection {
133
133
this . _logger . debug ( "Sending Frame" , {
134
134
data : { frame : frame . getRawData ( ) } ,
135
135
} ) ;
136
+
137
+ await this . waitUntilDeviceIsReady ( ) ;
138
+
136
139
try {
137
140
await this . _device . sendReport ( 0 , frame . getRawData ( ) ) ;
138
141
} catch ( error ) {
@@ -144,6 +147,18 @@ export class WebHidDeviceConnection implements DeviceConnection {
144
147
return resultPromise ;
145
148
}
146
149
150
+ private async waitUntilDeviceIsReady ( ) {
151
+ if ( this . timeOfReconnection . isJust ( ) ) {
152
+ const timeSinceReconnection =
153
+ Date . now ( ) - this . timeOfReconnection . extract ( ) ;
154
+ if ( timeSinceReconnection < 3000 ) {
155
+ await new Promise ( ( res ) =>
156
+ setTimeout ( ( ) => res ( undefined ) , 3000 - timeSinceReconnection ) ,
157
+ ) ;
158
+ }
159
+ }
160
+ }
161
+
147
162
private receiveHidInputReport ( event : HIDInputReportEvent ) {
148
163
const data = new Uint8Array ( event . data . buffer ) ;
149
164
this . _logger . debug ( "Received Frame" , {
@@ -178,14 +193,21 @@ export class WebHidDeviceConnection implements DeviceConnection {
178
193
const sub = this . reconnectionSubject . subscribe ( {
179
194
next : ( res ) => {
180
195
if ( waitingForDeviceResponse ) {
181
- this . _sendApduSubject . error ( new WebHidSendReportError ( ) ) ;
196
+ this . _sendApduSubject . error (
197
+ new WebHidSendReportError (
198
+ new Error (
199
+ "Device disconnected while waiting for device repsonse" ,
200
+ ) ,
201
+ ) ,
202
+ ) ;
182
203
}
183
204
184
205
if ( res === "success" ) {
185
206
resolve ( Right ( undefined ) ) ;
186
207
} else {
187
208
resolve ( Left ( res ) ) ;
188
209
}
210
+
189
211
sub . unsubscribe ( ) ;
190
212
} ,
191
213
} ) ;
@@ -198,7 +220,6 @@ export class WebHidDeviceConnection implements DeviceConnection {
198
220
* */
199
221
public lostConnection ( ) {
200
222
this . _logger . info ( "β±οΈ Lost connection, starting timer" ) ;
201
- this . timeSinceDisconnection = Maybe . of ( Date . now ( ) ) ;
202
223
this . waitingForReconnection = true ;
203
224
this . lostConnectionTimeout = setTimeout ( ( ) => {
204
225
this . _logger . info ( "β Disconnection timeout, terminating connection" ) ;
@@ -212,24 +233,13 @@ export class WebHidDeviceConnection implements DeviceConnection {
212
233
this . _device . oninputreport = ( event ) => this . receiveHidInputReport ( event ) ;
213
234
214
235
if ( this . lostConnectionTimeout ) {
215
- this . _logger . info ( "β±οΈπ Device reconnected" ) ;
216
236
clearTimeout ( this . lostConnectionTimeout ) ;
217
237
}
218
238
219
239
await device . open ( ) ;
240
+ this . _logger . info ( "β±οΈπ Device reconnected" ) ;
220
241
221
- if ( this . _pendingApdu . isJust ( ) ) {
222
- if ( this . timeSinceDisconnection . isJust ( ) ) {
223
- const now = Date . now ( ) ;
224
- const timeSinceDisconnection =
225
- now - this . timeSinceDisconnection . extract ( ) ;
226
- // 3 seconds timeout
227
- if ( timeSinceDisconnection > RECONNECT_DEVICE_TIMEOUT / 2 ) {
228
- this . _sendApduSubject . error ( new WebHidSendReportError ( ) ) ;
229
- }
230
- }
231
- this . timeSinceDisconnection = Nothing ;
232
- }
242
+ this . timeOfReconnection = Maybe . of ( Date . now ( ) ) ;
233
243
234
244
this . waitingForReconnection = false ;
235
245
this . reconnectionSubject . next ( "success" ) ;
0 commit comments