diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 75f85a7bd..ec6ebb2c0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1319,8 +1319,12 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_HF_FELICA_SNIFF: { - felica_sniff(packet->oldarg[0], packet->oldarg[1]); - reply_ng(CMD_HF_FELICA_SNIFF, PM3_SUCCESS, NULL, 0); + struct p { + uint32_t samples; + uint32_t triggers; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + felica_sniff(payload->samples, payload->triggers); break; } case CMD_HF_FELICALITE_DUMP: { diff --git a/armsrc/felica.c b/armsrc/felica.c index 3783c802f..182f496aa 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -572,23 +572,53 @@ void felica_sendraw(PacketCommandNG *c) { } void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { - int remFrames = (samplesToSkip) ? samplesToSkip : 0; - Dbprintf("Sniff Felica: Getting first %d frames, Skipping after %d triggers.\n", samplesToSkip, triggersToSkip); + clear_trace(); set_tracing(true); iso18092_setup(FPGA_HF_ISO18092_FLAG_NOMOD); + LED_D_ON(); - uint16_t numbts = 0; + + int retval = PM3_SUCCESS; + int remFrames = (samplesToSkip) ? samplesToSkip : 0; int trigger_cnt = 0; uint32_t timeout = iso18092_get_timeout(); bool isReaderFrame = true; - while (!BUTTON_PRESS()) { + + uint8_t flip = 0; + uint16_t checker = 0; + for (;;) { + WDT_HIT(); + + // since simulation is a tight time critical loop, + // we only check for user request to end at iteration 3000, 9000. + if (flip == 3) { + if (data_available()) { + retval = PM3_EOPABORTED; + break; + } + flip = 0; + } + + if (checker >= 3000) { + + if (BUTTON_PRESS()) { + retval = PM3_EOPABORTED; + break; + } + flip++; + checker = 0; + } + ++checker; + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); Process18092Byte(dist); + if ((dist >= 178) && (++trigger_cnt > triggersToSkip)) { - Dbprintf("triggersToSkip kicked %d", dist); + Dbprintf("triggers To skip kicked %d", dist); break; } if (FelicaFrame.state == STATE_FULL) { @@ -599,7 +629,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { } remFrames--; if (remFrames <= 0) { - Dbprintf("Stop Sniffing - samplesToSkip reached!"); + Dbprintf("Stop Sniffing - samples To skip reached!"); break; } LogTrace(FelicaFrame.framebytes, @@ -609,7 +639,6 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { NULL, isReaderFrame ); - numbts += FelicaFrame.len; FelicaFrameReset(); } } @@ -617,11 +646,9 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { switch_off(); //reset framing AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); - set_tracelen(numbts); - set_tracelen(BigBuf_max_traceLen()); - Dbprintf("Felica sniffing done, tracelen: %i, use " _YELLOW_("`hf felica list`") " for annotations", BigBuf_get_traceLen()); - reply_mix(CMD_ACK, 1, numbts, 0, 0, 0); + Dbprintf("Felica sniffing done, tracelen: %i", BigBuf_get_traceLen()); + reply_ng(CMD_HF_FELICA_SNIFF, retval, NULL, 0); LED_D_OFF(); } diff --git a/client/src/cmdhffelica.c b/client/src/cmdhffelica.c index 246d5bff3..8516b3ad3 100644 --- a/client/src/cmdhffelica.c +++ b/client/src/cmdhffelica.c @@ -121,20 +121,6 @@ static int usage_hf_felica_sim(void) { } */ -static int usage_hf_felica_sniff(void) { - PrintAndLogEx(NORMAL, "\nInfo: It get data from the field and saves it into command buffer. "); - PrintAndLogEx(NORMAL, " Buffer accessible from command 'hf felica list'"); - PrintAndLogEx(NORMAL, "\nUsage: hf felica sniff [-h] [-s] [-t]"); - PrintAndLogEx(NORMAL, " -h this help"); - PrintAndLogEx(NORMAL, " -s samples to skip (decimal) max 9999"); - PrintAndLogEx(NORMAL, " -t triggers to skip (decimal) max 9999"); - - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " hf felica sniff"); - PrintAndLogEx(NORMAL, " hf felica sniff -s 10 -t 10"); - return PM3_SUCCESS; -} - static int usage_hf_felica_request_service(void) { PrintAndLogEx(NORMAL, "\nInfo: Use this command to verify the existence of Area and Service, and to acquire Key Version:"); PrintAndLogEx(NORMAL, " - When the specified Area or Service exists, the card returns Key Version."); @@ -1376,57 +1362,67 @@ static int CmdHFFelicaNotImplementedYet(const char *Cmd) { } static int CmdHFFelicaSniff(const char *Cmd) { - uint8_t paramCount = 0; - uint64_t samples2skip = 0; - uint64_t triggers2skip = 0; - strip_cmds(Cmd); - int i = 0; - while (Cmd[i] != '\0') { - if (Cmd[i] == '-') { - switch (tolower(Cmd[i + 1])) { - case 'H': - return usage_hf_felica_sniff(); - case 's': - paramCount++; - if (param_getlength(Cmd, paramCount) < 5) { - samples2skip = param_get32ex(Cmd, paramCount++, 0, 10); - } else { - PrintAndLogEx(ERR, "Invalid samples number!"); - return PM3_EINVARG; - } - break; - case 't': - paramCount++; - if (param_getlength(Cmd, paramCount) < 5) { - triggers2skip = param_get32ex(Cmd, paramCount++, 0, 10); - } else { - PrintAndLogEx(ERR, "Invalid triggers number!"); - return PM3_EINVARG; - } - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, paramCount)); - return usage_hf_felica_sniff(); - } - i += 2; - } - i++; + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf felica sniff", + "Collect data from the field and save into command buffer.\n" + "Buffer accessible from `hf felica list`", + "hf felica sniff\n" + "hf felica sniff -s 10 -t 19" + ); + void *argtable[] = { + arg_param_begin, + arg_u64_0("s", "samples", "", "samples to skip"), + arg_u64_0("t", "trig", "", "triggers to skip "), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + + struct p { + uint32_t samples; + uint32_t triggers; + } PACKED payload; + + payload.samples = arg_get_u32_def(ctx, 1, 10); + payload.triggers = arg_get_u32_def(ctx, 2, 5000); + CLIParserFree(ctx); + + if (payload.samples > 9999 ){ + payload.samples = 9999; + PrintAndLogEx(INFO, "Too large samples to skip value, using max value 9999"); + return PM3_EINVARG; } - if (samples2skip == 0) { - samples2skip = 10; - PrintAndLogEx(INFO, "Set default samples2skip: %" PRIu64, samples2skip); + if (payload.triggers > 9999 ){ + payload.triggers = 9999; + PrintAndLogEx(INFO, "Too large trigger to skip value, using max value 9999"); + return PM3_EINVARG; } - if (triggers2skip == 0) { - triggers2skip = 5000; - PrintAndLogEx(INFO, "Set default triggers2skip: %" PRIu64, triggers2skip); - } - PrintAndLogEx(INFO, "Start Sniffing now. You can stop sniffing with clicking the PM3 Button"); - PrintAndLogEx(INFO, "During sniffing, other pm3 commands may not response."); + PrintAndLogEx(INFO, "Sniff Felica, getting first %" PRIu32 " frames, skipping after %" PRIu32 " triggers", payload.samples, payload.triggers ); + PrintAndLogEx(INFO, "Press " _GREEN_("") " or pm3-button to abort sniffing"); clearCommandBuffer(); - SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0); + SendCommandNG(CMD_HF_FELICA_SNIFF, (uint8_t *)&payload, sizeof(payload)); + PacketResponseNG resp; + + for (;;) { + if (kbd_enter_pressed()) { + SendCommandNG(CMD_BREAK_LOOP, NULL, 0); + PrintAndLogEx(DEBUG, "User aborted"); + msleep(300); + break; + } + + if (WaitForResponseTimeout(CMD_HF_FELICA_SNIFF, &resp, 1000)) { + if (resp.status == PM3_EOPABORTED) { + PrintAndLogEx(DEBUG, "Button pressed, user aborted"); + break; + } + } + } + + PrintAndLogEx(HINT, "try `" _YELLOW_("hf felica list") "` to view"); + PrintAndLogEx(INFO, "Done"); return PM3_SUCCESS; }