-int CmdVikingClone(const char *Cmd)
-{
- uint32_t b1,b2;
- // get the tag number 64 bits (8 bytes) in hex
- uint8_t id[8];
- if (param_gethex(Cmd,0,id,16) == 1)
- {
- PrintAndLog("Usage: lf viking clone <Card ID 16 bytes of hex number>");
- return 0;
- }
- b1 = bytes_to_num(id,sizeof(uint32_t));
- b2 = bytes_to_num(id + sizeof(uint32_t),sizeof(uint32_t));
- UsbCommand c = {CMD_VIKING_CLONE_TAG,{b1,b2}};
- SendCommand(&c);
+
+int usage_lf_viking_sim(void) {
+ PrintAndLog("Enables simulation of viking card with specified card number.");
+ PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
+ PrintAndLog("Per viking format, the card number is 8 digit hex number. Larger values are truncated.");
+ PrintAndLog("");
+ PrintAndLog("Usage: lf viking sim <Card-Number>");
+ PrintAndLog("Options :");
+ PrintAndLog(" <Card Number> : 8 digit hex viking card number");
+ PrintAndLog("");
+ PrintAndLog("Sample : lf viking sim 1A337");
+ return 0;
+}
+
+// calc checksum
+uint64_t getVikingBits(uint32_t id) {
+ uint8_t checksum = (id>>24) ^ ((id>>16) & 0xFF) ^ ((id>>8) & 0xFF) ^ (id & 0xFF) ^ 0xF2 ^ 0xA8;
+ uint64_t ret = (uint64_t)0xF2 << 56;
+ ret |= (id << 8);
+ ret |= checksum;
+ return ret;
+}
+//by marshmellow
+//see ASKDemod for what args are accepted
+int CmdVikingRead(const char *Cmd) {
+ // read lf silently
+ CmdLFRead("s");
+ // get samples silently
+ getSamples("30000",false);
+ // demod and output viking ID
+ return CmdVikingDemod(Cmd);
+}
+
+int CmdVikingClone(const char *Cmd) {
+ uint32_t id = 0;
+ uint64_t rawID = 0;
+ bool Q5 = false;
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_clone();
+
+ id = param_get32ex(Cmd, 0, 0, 16);
+ if (id == 0) return usage_lf_viking_clone();
+
+ cmdp = param_getchar(Cmd, 1);
+ if ( cmdp == 'Q' || cmdp == 'q')
+ Q5 = true;
+
+ rawID = getVikingBits(id);
+
+ UsbCommand c = {CMD_VIKING_CLONE_TAG,{rawID >> 32, rawID & 0xFFFF, Q5}};
+ clearCommandBuffer();
+ SendCommand(&c);
+ //check for ACK
+ WaitForResponse(CMD_ACK,NULL);