@@ -62,6 +62,7 @@ public class SmartCard extends BroadcastReceiver implements CardListener {
6262 private static final String WALLET_PATH = "m/44'/60'/0'/0/0" ;
6363 private static final String WHISPER_PATH = "m/43'/60'/1581'/0'/0" ;
6464 private static final String ENCRYPTION_PATH = "m/43'/60'/1581'/1'/0" ;
65+ private static final String TAG_LOST = "Tag was lost." ;
6566 private static final int WORDS_LIST_SIZE = 2048 ;
6667
6768 public SmartCard (ReactContext reactContext ) {
@@ -177,7 +178,7 @@ public boolean isNfcEnabled() {
177178 }
178179
179180 public SmartCardSecrets init (final String userPin ) throws IOException , APDUException , NoSuchAlgorithmException , InvalidKeySpecException {
180- KeycardCommandSet cmdSet = new KeycardCommandSet ( this . cardChannel );
181+ KeycardCommandSet cmdSet = commandSet ( );
181182 cmdSet .select ().checkOK ();
182183
183184 SmartCardSecrets s = SmartCardSecrets .generate (userPin );
@@ -186,7 +187,7 @@ public SmartCardSecrets init(final String userPin) throws IOException, APDUExcep
186187 }
187188
188189 public String pair (String pairingPassword ) throws IOException , APDUException {
189- KeycardCommandSet cmdSet = new KeycardCommandSet ( this . cardChannel );
190+ KeycardCommandSet cmdSet = commandSet ( );
190191 Log .i (TAG , "Applet selection successful" );
191192
192193 // First thing to do is selecting the applet on the card.
@@ -282,7 +283,7 @@ private boolean verifyAuthenticity(KeycardCommandSet cmdSet, String instanceUID)
282283 }
283284
284285 public WritableMap getApplicationInfo () throws IOException , APDUException {
285- KeycardCommandSet cmdSet = new KeycardCommandSet ( this . cardChannel );
286+ KeycardCommandSet cmdSet = commandSet ( );
286287 ApplicationInfo info = new ApplicationInfo (cmdSet .select ().checkOK ().getData ());
287288
288289 Log .i (TAG , "Card initialized? " + info .isInitializedCard ());
@@ -348,7 +349,7 @@ public WritableMap getApplicationInfo() throws IOException, APDUException {
348349 }
349350
350351 public WritableMap factoryResetPost () throws IOException , APDUException {
351- ApplicationInfo info = new ApplicationInfo (new KeycardCommandSet ( this . cardChannel ).select ().checkOK ().getData ());
352+ ApplicationInfo info = new ApplicationInfo (commandSet ( ).select ().checkOK ().getData ());
352353 Log .i (TAG , "Selecting the factory reset Keycard applet succeeded" );
353354
354355 WritableMap cardInfo = Arguments .createMap ();
@@ -358,7 +359,7 @@ public WritableMap factoryResetPost() throws IOException, APDUException {
358359 }
359360
360361 public WritableMap factoryResetFallback () throws IOException , APDUException {
361- GlobalPlatformCommandSet cmdSet = new GlobalPlatformCommandSet ( this . cardChannel );
362+ GlobalPlatformCommandSet cmdSet = gpCommandSet ( );
362363 cmdSet .select ().checkOK ();
363364 Log .i (TAG , "ISD selected" );
364365
@@ -375,7 +376,7 @@ public WritableMap factoryResetFallback() throws IOException, APDUException {
375376 }
376377
377378 public WritableMap factoryReset () throws IOException , APDUException {
378- KeycardCommandSet cmdSet = new KeycardCommandSet ( this . cardChannel );
379+ KeycardCommandSet cmdSet = commandSet ( );
379380 APDUResponse resp = cmdSet .select ();
380381
381382 if (!resp .isOK ()) {
@@ -661,7 +662,7 @@ public String signWithPath(final String pin, final String path, final String mes
661662 }
662663
663664 public String signPinless (final String message ) throws IOException , APDUException {
664- CashCommandSet cmdSet = new CashCommandSet ( this . cardChannel );
665+ CashCommandSet cmdSet = cashCommandSet ( );
665666 cmdSet .select ().checkOK ();
666667
667668 byte [] hash = Hex .decode (message );
@@ -685,7 +686,7 @@ public String signPinless(final String message) throws IOException, APDUExceptio
685686 }
686687
687688 public String getCardName () throws IOException , APDUException {
688- KeycardCommandSet cmdSet = new KeycardCommandSet ( this . cardChannel );
689+ KeycardCommandSet cmdSet = commandSet ( );
689690 cmdSet .select ().checkOK ();
690691 return getCardNameOrDefault (cmdSet );
691692 }
@@ -698,7 +699,7 @@ public void setCardName(final String pin, final String name) throws IOException,
698699 }
699700
700701 public WritableMap verifyCard (final String challenge ) throws IOException , APDUException {
701- KeycardCommandSet cmdSet = new KeycardCommandSet ( this . cardChannel );
702+ KeycardCommandSet cmdSet = commandSet ( );
702703 cmdSet .select ().checkOK ();
703704 byte [] rawChallenge = Hex .decode (challenge );
704705 byte [] data = cmdSet .identifyCard (rawChallenge ).checkOK ().getData ();
@@ -742,13 +743,43 @@ private KeycardCommandSet authenticatedCommandSet(String pin) throws IOException
742743 }
743744
744745 private KeycardCommandSet securedCommandSet () throws IOException , APDUException {
745- KeycardCommandSet cmdSet = new KeycardCommandSet ( this . cardChannel );
746+ KeycardCommandSet cmdSet = commandSet ( );
746747 cmdSet .select ().checkOK ();
747748 openSecureChannel (cmdSet );
748749
749750 return cmdSet ;
750751 }
751752
753+ private KeycardCommandSet commandSet () throws IOException {
754+ synchronized (lock ) {
755+ if (this .cardChannel != null ) {
756+ return new KeycardCommandSet (this .cardChannel );
757+ }
758+ }
759+
760+ throw new IOException (TAG_LOST );
761+ }
762+
763+ private CashCommandSet cashCommandSet () throws IOException {
764+ synchronized (lock ) {
765+ if (this .cardChannel != null ) {
766+ return new CashCommandSet (this .cardChannel );
767+ }
768+ }
769+
770+ throw new IOException (TAG_LOST );
771+ }
772+
773+ private GlobalPlatformCommandSet gpCommandSet () throws IOException {
774+ synchronized (lock ) {
775+ if (this .cardChannel != null ) {
776+ return new GlobalPlatformCommandSet (this .cardChannel );
777+ }
778+ }
779+
780+ throw new IOException (TAG_LOST );
781+ }
782+
752783 private String getCardNameOrDefault (KeycardCommandSet cmdSet ) throws IOException , APDUException {
753784 byte [] data = cmdSet .getData (KeycardCommandSet .STORE_DATA_P1_PUBLIC ).checkOK ().getData ();
754785
0 commit comments