+
+int EMVSelectWithRetry(EMVCommandChannel channel, bool ActivateField, bool LeaveFieldON, uint8_t *AID, size_t AIDLen, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw, struct tlvdb *tlv) {
+ int retrycnt = 0;
+ int res = 0;
+ do {
+ res = EMVSelect(channel, false, true, AID, AIDLen, Result, MaxResultLen, ResultLen, sw, tlv);
+
+ // retry if error and not returned sw error
+ if (res && res != 5) {
+ if (++retrycnt < 3){
+ continue;
+ } else {
+ // card select error, proxmark error
+ if (res == 1) {
+ PrintAndLogEx(WARNING, "Exit...");
+ return 1;
+ }
+
+ retrycnt = 0;
+ PrintAndLogEx(NORMAL, "Retry failed [%s]. Skiped...", sprint_hex_inrow(AID, AIDLen));
+ return res;
+ }
+ }
+ } while (res && res != 5);
+
+ return res;
+}
+
+
+int EMVCheckAID(EMVCommandChannel channel, bool decodeTLV, struct tlvdb *tlvdbelm, struct tlvdb *tlv){
+ uint8_t data[APDU_RESPONSE_LEN] = {0};
+ size_t datalen = 0;
+ int res = 0;
+ uint16_t sw = 0;
+
+ while (tlvdbelm) {
+ const struct tlv *tgAID = tlvdb_get_inchild(tlvdbelm, 0x4f, NULL);
+ if (tgAID) {
+ res = EMVSelectWithRetry(channel, false, true, (uint8_t *)tgAID->value, tgAID->len, data, sizeof(data), &datalen, &sw, tlv);
+
+ // if returned sw error
+ if (res == 5) {
+ // next element
+ tlvdbelm = tlvdb_find_next(tlvdbelm, 0x61);
+ continue;
+ }
+
+ if (res)
+ break;
+
+ // all is ok
+ if (decodeTLV){
+ PrintAndLogEx(NORMAL, "%s:", sprint_hex_inrow(tgAID->value, tgAID->len));
+ TLVPrintFromBuffer(data, datalen);
+ }
+ }
+ tlvdbelm = tlvdb_find_next(tlvdbelm, 0x61);
+ }
+ return res;
+}
+
+