+       // transaction check
+       const struct tlv *AIPtlv = tlvdb_get(tlvRoot, 0x82, NULL);      
+       uint16_t AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100;
+       PrintAndLog("* * AIP=%x", AIP);
+
+       // qVSDC
+       {
+               // 9F26: Application Cryptogram
+               const struct tlv *AC = tlvdb_get(tlvRoot, 0x9F26, NULL);
+               if (AC) {
+                       PrintAndLog("\n--> qVSDC transaction.");
+                       PrintAndLog("* AC path");
+                       
+                       // 9F36: Application Transaction Counter (ATC)
+                       const struct tlv *ATC = tlvdb_get(tlvRoot, 0x9F36, NULL);
+                       if (ATC) {
+                       
+                               // 9F10: Issuer Application Data - optional
+                               const struct tlv *IAD = tlvdb_get(tlvRoot, 0x9F10, NULL);
+
+                               // print AC data
+                               PrintAndLog("ATC: %s", sprint_hex(ATC->value, ATC->len));
+                               PrintAndLog("AC: %s", sprint_hex(AC->value, AC->len));
+                               if (IAD){
+                                       PrintAndLog("IAD: %s", sprint_hex(IAD->value, IAD->len));
+                                       
+                                       if (IAD->len >= IAD->value[0] + 1) {
+                                               PrintAndLog("\tKey index:  0x%02x", IAD->value[1]);
+                                               PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
+                                               PrintAndLog("\tCVR:", sprint_hex(&IAD->value[3], IAD->value[0] - 2));
+                                               struct tlvdb * cvr = tlvdb_fixed(0x20, IAD->value[0] - 2, &IAD->value[3]);
+                                               TLVPrintFromTLVLev(cvr, 1);
+                                       }
+                               } else {
+                                       PrintAndLog("WARNING: IAD not found.");
+                               }
+                               
+                       } else {
+                               PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
+                       }
+               }
+       }
+       
+       // TODO: Mastercard M/CHIP
+       {
+               const struct tlv *CDOL1 = tlvdb_get(tlvRoot, 0x8c, NULL);
+               if (CDOL1 && GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) { // and m/chip transaction flag
+               
+               }
+       }
+               
+       // MSD
+       if (AIP & 0x8000) {
+               PrintAndLog("\n--> MSD transaction.");
+               
+               
+               PrintAndLog("* MSD dCVV path. Check dCVV");
+
+               const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
+               if (track2) {
+                       PrintAndLog("Track2: %s", sprint_hex(track2->value, track2->len));
+
+                       struct tlvdb *dCVV = GetdCVVRawFromTrack2(track2);
+                       PrintAndLog("dCVV raw data:");
+                       TLVPrintFromTLV(dCVV);
+                       
+                       if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) {
+                               PrintAndLog("\n* Mastercard calculate UDOL");
+
+                               // UDOL (9F69)
+                               const struct tlv *UDOL = tlvdb_get(tlvRoot, 0x9F69, NULL);
+                               // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
+                               const struct tlv defUDOL = {
+                                       .tag = 0x01,
+                                       .len = 3,
+                                       .value = (uint8_t *)"\x9f\x6a\x04",
+                               };
+                               if (!UDOL)
+                                       PrintAndLog("Use default UDOL.");
+
+                               struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - fake tag!
+                               if (!udol_data_tlv){
+                                       PrintAndLog("ERROR: can't create UDOL TLV.");
+                                       return 4;
+                               }
+
+                               PrintAndLog("UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len));
+                               
+                               PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
+                               
+                               res = MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv->value, udol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
+                               if (res) {
+                                       PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw);
+                                       return 5;
+                               }
+                               
+                               if (decodeTLV) {
+                                       TLVPrintFromBuffer(buf, len);
+                                       PrintAndLog("");
+                               }
+
+                       }
+               } else {
+                       PrintAndLog("ERROR MSD: Track2 data not found.");
+               }
+       }
+       
+       // additional contacless EMV commands (fDDA, external authenticate)