#include "sd_card_id.h" #include namespace roro { namespace { char printable(uint8_t b) { return b >= 0x20 && b < 0x7F ? static_cast(b) : '?'; } } // namespace SdCardId parseSdCid(const uint8_t cid[16]) { SdCardId id; id.manufacturer = cid[0]; for (int i = 0; i < 2; ++i) id.oem[i] = printable(cid[1 + i]); for (int i = 0; i < 5; ++i) id.product[i] = printable(cid[3 + i]); id.revisionMajor = cid[8] >> 4; id.revisionMinor = cid[8] & 0x0F; id.serial = static_cast(cid[9]) << 24 | cid[10] << 16 | cid[11] << 8 | cid[12]; // 4 reserved bits, 8 bits of year since 2000, 4 bits of month. id.year = 2000 + (((cid[13] & 0x0F) << 4) | (cid[14] >> 4)); id.month = cid[14] & 0x0F; return id; } const char* sdManufacturerName(uint8_t id) { switch (id) { case 0x01: return "Panasonic"; case 0x02: return "Toshiba/Kioxia"; case 0x03: return "SanDisk"; case 0x1B: return "Samsung"; case 0x1D: return "ADATA"; case 0x27: return "Phison"; case 0x28: return "Lexar"; case 0x31: return "Silicon Power"; case 0x41: return "Kingston"; case 0x74: return "Transcend"; case 0x76: return "Patriot"; case 0x82: return "Sony"; case 0x9C: return "Angelbird/Hoodman"; case 0xAD: return "Longsys/Lexar"; default: return "unknown"; } } std::string sdCardSummary(const SdCardId& id) { char s[112]; std::snprintf(s, sizeof s, "%s (0x%02X) \"%s\" \"%s\" rev %u.%u, serial %08x, made %04d-%02d", sdManufacturerName(id.manufacturer), id.manufacturer, id.oem, id.product, id.revisionMajor, id.revisionMinor, static_cast(id.serial), id.year, id.month); return s; } } // namespace roro