diff --git a/client/cmdlfmotorola.c b/client/cmdlfmotorola.c new file mode 100644 index 000000000..32410b8d7 --- /dev/null +++ b/client/cmdlfmotorola.c @@ -0,0 +1,136 @@ +//----------------------------------------------------------------------------- +// Iceman, 2019 +// +// 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 Motorola tag commands +// PSK1, RF/32, 64 bits long, at 74 kHz +//----------------------------------------------------------------------------- +#include "cmdlfmotorola.h" + +#include //tolower + +#include "commonutil.h" // ARRAYLEN +#include "common.h" +#include "cmdparser.h" // command_t +#include "comms.h" +#include "ui.h" +#include "cmddata.h" +#include "cmdlf.h" +#include "lfdemod.h" // preamble test +#include "protocols.h" // t55xx defines +#include "cmdlft55xx.h" // clone.. +#include "cmdlf.h" // cmdlfconfig + +static int CmdHelp(const char *Cmd); + +//see PSKDemod for what args are accepted +static int CmdMotorolaDemod(const char *Cmd) { + + //PSK1 + if (PSKDemod("32 1", true) != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: PSK Demod failed"); + return PM3_ESOFT; + } + size_t size = DemodBufferLen; + int ans = detectMotorola(DemodBuffer, &size); + if (ans < 0) { + if (ans == -1) + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: too few bits found"); + else if (ans == -2) + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: preamble not found"); + else if (ans == -3) + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: Size not correct: %zu", size); + else + PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: ans: %d", ans); + + return PM3_ESOFT; + } + setDemodBuff(DemodBuffer, 64, ans); + setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock)); + + //got a good demod + uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32); + uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32); + + PrintAndLogEx(SUCCESS, "Motorola Tag Found -- Raw: %08X%08X", raw1, raw2); + PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum"); + return PM3_SUCCESS; +} + +static int CmdMotorolaRead(const char *Cmd) { + // Motorola Flexpass seem to work at 74 kHz + // and take about 4400 samples to befor modulating + sample_config sc = { + .decimation = 0, + .bits_per_sample = 0, + .averaging= false, + .divisor = LF_DIVISOR(74), + .trigger_threshold = -1, + .samples_to_skip = 4500, + .verbose = false + }; + lf_config(&sc); + + // 64 * 32 * 2 * n-ish + lf_read(true, 5000); + + // reset back to 125 kHz + sc.divisor = LF_DIVISOR_125; + sc.samples_to_skip = 0; + lf_config(&sc); + return CmdMotorolaDemod(Cmd); +} + +static int CmdMotorolaSim(const char *Cmd) { + + // PSK sim. + PrintAndLogEx(INFO, " PSK1 at 66 kHz... Interesting."); + PrintAndLogEx(INFO, " To be implemented, feel free to contribute!"); + return PM3_SUCCESS; +} + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdMotorolaDemod, AlwaysAvailable, "Demodulate an MOTOROLA tag from the GraphBuffer"}, + {"read", CmdMotorolaRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"}, + {"sim", CmdMotorolaSim, IfPm3Lf, "simulate MOTOROLA tag"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdLFMotorola(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} + +// find MOTOROLA preamble in already demoded data +int detectMotorola(uint8_t *dest, size_t *size) { + if (*size < 64) return -1; //make sure buffer has data + size_t startIdx = 0; + uint8_t preamble[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1 + }; + if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx)) + return -2; //preamble not found + if (*size != 64) return -3; //wrong demoded size + //return start position + return (int)startIdx; +} + +int demodMotorola(void) { + return CmdMotorolaDemod(""); +} + +int readMotorolaUid(void) { + return ( CmdMotorolaRead("") == PM3_SUCCESS); +} diff --git a/client/cmdlfmotorola.h b/client/cmdlfmotorola.h new file mode 100644 index 000000000..682193ebc --- /dev/null +++ b/client/cmdlfmotorola.h @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------- +// Iceman, 2019 +// +// 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 MOTOROLA tag commands +//----------------------------------------------------------------------------- +#ifndef CMDLFMOTOROLA_H__ +#define CMDLFMOTOROLA_H__ + +#include "common.h" + +int CmdLFMotorola(const char *Cmd); + +int demodMotorola(void); +int detectMotorola(uint8_t *dest, size_t *size); +int readMotorolaUid(void); +#endif +