2017-03-28 06:04:20 +08:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
|
|
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
|
|
|
// the license.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Low frequency Honeywell NexWatch tag commands
|
2017-04-08 05:28:12 +08:00
|
|
|
// PSK1 RF/16, RF/2, 128 bits long (known)
|
2017-03-28 06:04:20 +08:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include "cmdlfnexwatch.h"
|
|
|
|
#include "proxmark3.h"
|
|
|
|
#include "ui.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "graph.h"
|
|
|
|
#include "cmdparser.h"
|
|
|
|
#include "cmddata.h"
|
|
|
|
#include "cmdlf.h"
|
|
|
|
#include "lfdemod.h"
|
|
|
|
|
|
|
|
static int CmdHelp(const char *Cmd);
|
|
|
|
|
|
|
|
int CmdPSKNexWatch(const char *Cmd)
|
|
|
|
{
|
|
|
|
if (!PSKDemod("", false)) return 0;
|
|
|
|
uint8_t preamble[28] = {0,0,0,0,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
|
|
size_t startIdx = 0, size = DemodBufferLen;
|
|
|
|
bool invert = false;
|
|
|
|
if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)){
|
|
|
|
// if didn't find preamble try again inverting
|
|
|
|
if (!PSKDemod("1", false)) return 0;
|
|
|
|
size = DemodBufferLen;
|
|
|
|
if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)) return 0;
|
|
|
|
invert = true;
|
|
|
|
}
|
|
|
|
if (size != 128) return 0;
|
|
|
|
setDemodBuf(DemodBuffer, size, startIdx+4);
|
2017-04-13 05:55:31 +08:00
|
|
|
setClockGrid(g_DemodClock, g_DemodStartIdx + ((startIdx+4)*g_DemodClock));
|
|
|
|
startIdx = 8+32; // 8 = preamble, 32 = reserved bits (always 0)
|
2017-03-28 06:04:20 +08:00
|
|
|
//get ID
|
|
|
|
uint32_t ID = 0;
|
|
|
|
for (uint8_t wordIdx=0; wordIdx<4; wordIdx++){
|
|
|
|
for (uint8_t idx=0; idx<8; idx++){
|
|
|
|
ID = (ID << 1) | DemodBuffer[startIdx+wordIdx+(idx*4)];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//parity check (TBD)
|
|
|
|
|
|
|
|
//checksum check (TBD)
|
|
|
|
|
|
|
|
//output
|
|
|
|
PrintAndLog("NexWatch ID: %d", ID);
|
|
|
|
if (invert){
|
|
|
|
PrintAndLog("Had to Invert - probably NexKey");
|
|
|
|
for (uint8_t idx=0; idx<size; idx++)
|
|
|
|
DemodBuffer[idx] ^= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
CmdPrintDemodBuff("x");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//by marshmellow
|
|
|
|
//see ASKDemod for what args are accepted
|
|
|
|
int CmdNexWatchRead(const char *Cmd) {
|
|
|
|
// read lf silently
|
2017-04-08 05:28:12 +08:00
|
|
|
lf_read(true, 10000);
|
2017-03-28 06:04:20 +08:00
|
|
|
// demod and output viking ID
|
|
|
|
return CmdPSKNexWatch(Cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static command_t CommandTable[] = {
|
|
|
|
{"help", CmdHelp, 1, "This help"},
|
|
|
|
{"demod", CmdPSKNexWatch, 1, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
|
|
|
|
{"read", CmdNexWatchRead, 0, "Attempt to Read and Extract tag data from the antenna"},
|
|
|
|
{NULL, NULL, 0, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
int CmdLFNexWatch(const char *Cmd) {
|
|
|
|
CmdsParse(CommandTable, Cmd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CmdHelp(const char *Cmd) {
|
|
|
|
CmdsHelp(CommandTable);
|
|
|
|
return 0;
|
|
|
|
}
|