Merge remote-tracking branch 'origin/main'

This commit is contained in:
dxl
2023-10-19 22:51:55 +08:00
18 changed files with 554 additions and 535 deletions
+4 -1
View File
@@ -3,7 +3,10 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Nested and StaticNested multithreaded decryption.
- Fixed `hf 14a raw` command raising `AttributeError` (@augustozanellato)
- Fixed ATS handling in tags that NAK RATS (@augustozanellato)
- Changed battery level curves based on experimental measures (@spp2000)
- Added multithreading on Nested and StaticNested (@xianglin1998)
- Fixed factory reset hanging (@augustozanellato)
- Changed fds_write_sync to take length in bytes instead of next multiple of 4 (@doegox)
- Fixed field LED when LF reading and HF cloning (@doegox)
+63 -45
View File
@@ -104,33 +104,44 @@ To run again after installing, just do the following:
### Linux
1. Install the dependencies
- Ubuntu / Debian: `sudo apt install cmake make python3 python3-pip git ninja-build python3-venv build-essential`
- Arch: `sudo pacman -S cmake make python3-pip git ninja base-devel`
Install the dependencies
- Ubuntu / Debian:
`sudo apt install git cmake build-essential python3-venv`
- Arch:
`sudo pacman -S git cmake base-devel python3`
2. Clone the Repository by typing `git clone https://github.com/RfidResearchGroup/ChameleonUltra.git`
Run the following script to clone the Repository, compile the tools and install Python dependencies in a virtual environment.
3. Now go into the newly created folder with `cd ChameleonUltra/software/src`
```sh
#!/bin/bash
4. Build the required config by running `cmake .`
git clone https://github.com/RfidResearchGroup/ChameleonUltra.git
(
cd ChameleonUltra/software/src
mkdir -p out
(
cd out
cmake ..
cmake --build . --config Release
)
)
(
cd ChameleonUltra/software/script
python3 -m venv venv
source venv/bin/activate
pip3 install -r requirements.txt
deactivate
)
```
5. And the binaries with `cmake --build .`
To run the client after installing, do the following:
6. Go into the script folder with `cd ../script/`
7. Create a virtual enviroment with `python3 -m venv venv`
8. Activate it with `source venv/bin/activate`
9. Install python requirements with `pip3 install -r requirements.txt`
10. Finally run the CLI with `python3 chameleon_cli_main.py`
To run again after installing, just do the following:
1. Activate venv by running `source venv/bin/activate`
2. Run the CLI with `python3 chameleon_cli_main.py`
```sh
cd ChameleonUltra/software/script
source venv/bin/activate
python3 chameleon_cli_main.py
deactivate
```
### MacOS
@@ -140,31 +151,41 @@ To run again after installing, just do the following:
When in the CLI, plug in your Chameleon and connect with `hw connect`. If autodetection fails, get the Serial Port used by your Chameleon and run `hw connect -p COM11` (Replace `COM11` with your serial port, on Linux it may be `/dev/ttyACM0`)
### Common activities
- Connect to the CLI: `hw connect`
- Change slot: `hw slot change -s [1-8]`
*More examples coming soon*
### MFKEY32v2 walk-through
Make sure to be in the `software/` directory and run the Python CLI from there.
- Connect to the CLI: `hw connect`
- Check which slot can be used: `hw slot list`
- Change the slot type, here using slot 8 for a MFC 1k emulation: `hw slot type -s 8 -t MIFARE_1024`
- Init the slot content: `hw slot init -s 8 -t MIFARE_1024`
- or load an existing dump and set UID and anticollision data, cf `hf mf eload -h` and `hf mf econfig -h`
- Enable the slot: `hw slot enable -s 8 --hf`
- Change to the new slot: `hw slot change -s 8`
- Activate the authentication logs: `hf mf econfig --enable-log`
```sh
# Connect to the CLI
hw connect
# Check which slot can be used
hw slot list
# Change the slot type, here using slot 8 for a MFC 1k emulation
hw slot type -s 8 -t MIFARE_1024
# Init the slot content
hw slot init -s 8 -t MIFARE_1024
# or load an existing dump and set UID and anticollision data,
# cf 'hf mf eload' and 'hf mf econfig'
# Enable the slot
hw slot enable -s 8 --hf
# Change to the new slot
hw slot change -s 8
# Activate the authentication logs
hf mf econfig --enable-log
```
Now disconnect, go to a reader and swipe it a few times
- Come back and connect to the CLI: `hw connect`
- See if nonces were collected: `hf mf elog`
- We need 2 nonces per key to recover
- Recover the key(s) based on the collected nonces: `hf mf elog --decrypt`.
Come back
```sh
# connect to the CLI
hw connect
# See if nonces were collected. We need 2 nonces per key to recover
hf mf elog
# Recover the key(s) based on the collected nonces
hf mf elog --decrypt
# Clean the logged detection nonces
hf mf econfig --disable-log
```
Output example:
```
- MF1 detection log count = 6, start download.
@@ -178,8 +199,5 @@ Now disconnect, go to a reader and swipe it a few times
```
- To clean the logged detection nonces: `hf mf econfig --disable-log` then `hf mf econfig --enable-log`
*More examples coming soon*
+5 -5
View File
@@ -50,7 +50,7 @@ E.g. LRC3(DATA) == LRC3(whole frame)
Each command and response have their own payload formats.
Standard response status is `STATUS_DEVICE_SUCCESS` for general commands, `HF_TAG_OK` for HF commands and `LF_TAG_OK` for LF commands.
Standard response status is `STATUS_SUCCESS` for general commands, `STATUS_HF_TAG_OK` for HF commands and `STATUS_LF_TAG_OK` for LF commands.
See [Guidelines](#new-data-payloads-guidelines-for-developers) for more info.
Beware, slots in protocol count from 0 to 7 (and from 1 to 8 in the CLI...).
@@ -144,7 +144,7 @@ Notes: the returned string is the output of `git describe --abbrev=7 --dirty --a
* CLI: cf `hw slot list`
### 1020: WIPE_FDS
* Command: no data
* Response: no data. Status is `STATUS_DEVICE_SUCCESS` or `STATUS_FLASH_WRITE_FAIL`. The device will reboot shortly after this command.
* Response: no data. Status is `STATUS_SUCCESS` or `STATUS_FLASH_WRITE_FAIL`. The device will reboot shortly after this command.
* CLI: cf `hw factory_reset`
### 1021: DELETE_SLOT_TAG_NICK
* Command: 2 bytes. `slot_number|sense_type` with `slot_number` between 0 and 7 and `sense_type` according to `tag_sense_type_t` enum.
@@ -226,7 +226,7 @@ Notes: wait about 5 seconds after wake-up, before querying the battery status, e
* CLI: cf `hf 14a scan`
Notes:
* remind that if no tag is present, status will be `HF_TAG_NO` and Response empty.
* remind that if no tag is present, status will be `STATUS_HF_TAG_NO` and Response empty.
* at the moment, the firmware supports only one tag, but get your client ready for more!
* `atslen` must not be confused with `ats[0]`==`TL`. So `atslen|ats` = `00` means no ATS while `0100` would be an empty ATS.
### 2001: MF1_DETECT_SUPPORT
@@ -269,7 +269,7 @@ Notes:
### 2007: MF1_AUTH_ONE_KEY_BLOCK
* Command: 8 bytes: `type|block|key[6]`. Key as 6 bytes. Type=0x60 for key A, 0x61 for key B.
* Response: no data
* Status will be `HF_TAG_OK` if auth succeeded, else `MF_ERR_AUTH`
* Status will be `STATUS_HF_TAG_OK` if auth succeeded, else `STATUS_MF_ERR_AUTH`
* CLI: cf `hf mf nested`
### 2008: MF1_READ_ONE_BLOCK
* Command: 8 bytes: `type|block|key[6]`. Key as 6 bytes. Type=0x60 for key A, 0x61 for key B.
@@ -397,7 +397,7 @@ Be verbose, explicit and reuse conventions, in order to enhance code maintainabi
- Avoid hardcoding offsets, use `sizeof()`, `offsetof(struct, field)` in C and `struct.calcsize()` in Python
- For complex bitfield structs, exceptionally you can use ctypes in Python. Beware ctypes.BigEndianStructure bitfield will be parsed in the firmware in the reverse order, from LSB to MSB.
### Guideline: Status
If single byte of data to return, still use a 1-byte `data`, not `status`. Standard response status is `STATUS_DEVICE_SUCCESS` for general commands, `HF_TAG_OK` for HF commands and `LF_TAG_OK` for LF commands. If the response status is different than those, the response data is empty. Response status are generic and cover things like tag disappearance or tag non-conformities with the ISO standard. If a command needs more specific response status, it is added in the first byte of the data, to avoid cluttering the 1-byte general status enum with command-specific statuses. See e.g. [MF1_DARKSIDE_ACQUIRE](#2004-mf1_darkside_acquire).
If single byte of data to return, still use a 1-byte `data`, not `status`. Standard response status is `STATUS_SUCCESS` for general commands, `STATUS_HF_TAG_OK` for HF commands and `STATUS_LF_TAG_OK` for LF commands. If the response status is different than those, the response data is empty. Response status are generic and cover things like tag disappearance or tag non-conformities with the ISO standard. If a command needs more specific response status, it is added in the first byte of the data, to avoid cluttering the 1-byte general status enum with command-specific statuses. See e.g. [MF1_DARKSIDE_ACQUIRE](#2004-mf1_darkside_acquire).
### Guideline: unambiguous types
- Use unambiguous types such as `uint16_t`, not `int` or `enum`. Cast explicitly `int` and `enum` to `uint_t` of proper size
- Use Network byte order for 16b and 32b integers
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -620,7 +620,7 @@ static void btn_fn_copy_ic_uid(void) {
case TAG_TYPE_EM410X:
status = PcdScanEM410X(id_buffer);
if (status == LF_TAG_OK) {
if (status == STATUS_LF_TAG_OK) {
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
memcpy(buffer->buffer, id_buffer, LF_EM410X_TAG_ID_SIZE);
tag_emulation_load_by_buffer(TAG_TYPE_EM410X, false);
@@ -680,7 +680,7 @@ static void btn_fn_copy_ic_uid(void) {
status = pcd_14a_reader_scan_auto(&tag);
pcd_14a_reader_antenna_off();
if (status == HF_TAG_OK) {
if (status == STATUS_HF_TAG_OK) {
// copy uid
antres->size = tag.uid_len;
memcpy(antres->uid, tag.uid, tag.uid_len);
+12 -12
View File
@@ -5,21 +5,21 @@
/////////////////////////////////////////////////////////////////////
// 14a status
/////////////////////////////////////////////////////////////////////
#define HF_TAG_OK (0x00) // IC card operation successful
#define HF_TAG_NO (0x01) // No IC card found
#define HF_ERR_STAT (0x02) // IC Card communication error
#define HF_ERR_CRC (0x03) // IC Card communication verification error
#define HF_COLLISION (0x04) // IC card conflict
#define HF_ERR_BCC (0x05) // IC card BCC error
#define MF_ERR_AUTH (0x06) // MF card verification failed
#define HF_ERR_PARITY (0x07) // IC card parity error
#define HF_ERR_ATS (0x08) // ATS should be present but card NAKed
#define STATUS_HF_TAG_OK (0x00) // IC card operation successful
#define STATUS_HF_TAG_NO (0x01) // No IC card found
#define STATUS_HF_ERR_STAT (0x02) // IC Card communication error
#define STATUS_HF_ERR_CRC (0x03) // IC Card communication verification error
#define STATUS_HF_COLLISION (0x04) // IC card conflict
#define STATUS_HF_ERR_BCC (0x05) // IC card BCC error
#define STATUS_MF_ERR_AUTH (0x06) // MF card verification failed
#define STATUS_HF_ERR_PARITY (0x07) // IC card parity error
#define STATUS_HF_ERR_ATS (0x08) // ATS should be present but card NAKed
/////////////////////////////////////////////////////////////////////
// lf status
/////////////////////////////////////////////////////////////////////
#define LF_TAG_OK (0x40) // Some of the low -frequency cards are successful!
#define EM410X_TAG_NO_FOUND (0x41) // Can't search for valid EM410X tags
#define STATUS_LF_TAG_OK (0x40) // Some of the low -frequency cards are successful!
#define STATUS_EM410X_TAG_NO_FOUND (0x41) // Can't search for valid EM410X tags
/////////////////////////////////////////////////////////////////////
@@ -28,7 +28,7 @@
#define STATUS_PAR_ERR (0x60) // The parameter errors transferred by the BLE instruction, or call the parameter error transmitted by certain functions
#define STATUS_DEVICE_MODE_ERROR (0x66) // The mode of the current device is wrong, and the corresponding API cannot be called
#define STATUS_INVALID_CMD (0x67) // Invalid instruction
#define STATUS_DEVICE_SUCCESS (0x68) // Device -related operations successfully executed
#define STATUS_SUCCESS (0x68) // Device -related operations successfully executed
#define STATUS_NOT_IMPLEMENTED (0x69) // Calling some unrealized operations, which belongs to the missed error of the developer
#define STATUS_FLASH_WRITE_FAIL (0x70) // Flash writing failed
#define STATUS_FLASH_READ_FAIL (0x71) // Flash read failed
+17 -36
View File
@@ -226,44 +226,25 @@ __INLINE uint32_t map(uint32_t x, uint32_t in_min, uint32_t in_max, uint32_t out
//Battery voltage to percentage calculation
uint32_t BATVOL2PERCENT(uint16_t VOL) {
//100% 4.20V 1
//90 % 4.06V 80%-100% white
//80 % 3.98V 1
//70 % 3.92V 60%-80% white
//60 % 3.87V 1
//50 % 3.82V 40%-60% white
//40 % 3.79V 1
//30 % 3.77V 20%-40% white
//20 % 3.74V 1
//10 % 3.68V 5%-20% red
//5 % 3.45V 1 Turn off
//0 % 3.00V
//#define P100VOL 4200
//#define P80VOL 3980
//#define P60VOL 3870
//#define P40VOL 3790
//#define P20VOL 3740
//#define P5VOL 3450
// Based on https://github.com/RfidResearchGroup/ChameleonUltra/issues/167#issuecomment-1766908799
//100% 4.20V 1
//90 % 4.00V 80%-100% white
//80 % 3.89V 1
//70 % 3.79V 60%-80% white
//60 % 3.70V 1
//50 % 3.62V 40%-60% white
//40 % 3.57V 1
//30 % 3.53V 20%-40% white
//20 % 3.51V 1
//10 % 3.46V 5%-20% red
//5 % 3.43V 1 Turn off
//0 % 3.00V
#if defined(PROJECT_CHAMELEON_ULTRA)
// Ultra
#define P100VOL 4200
#define P80VOL 3890
#define P60VOL 3700
#define P40VOL 3570
#define P20VOL 3510
#define P5VOL 3230
#define P80VOL 4034
#define P60VOL 3904
#define P40VOL 3824
#define P20VOL 3754
#define P5VOL 3644
#else
// Lite
#define P100VOL 4200
#define P80VOL 3934
#define P60VOL 3844
#define P40VOL 3784
#define P20VOL 3744
#define P5VOL 3644
#endif
if (VOL > P80VOL) {
//80-100
@@ -138,7 +138,7 @@ static uint8_t send_cmd(struct Crypto1State *pcs, uint8_t encrypted, uint8_t cmd
}
// There is a problem with communication, do not continue the next task
if (*status != HF_TAG_OK) {
if (*status != STATUS_HF_TAG_OK) {
return len;
}
@@ -184,7 +184,7 @@ int authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyT
len = send_cmd(pcs, isNested, keyType, blockNo, &status, answer, parity, U8ARR_BIT_LEN(answer));
if (len != 32) {
NRF_LOG_INFO("No 32 data recv on send_cmd: %d\r\n", len);
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
// Save the tag nonce (nt)
@@ -232,15 +232,15 @@ int authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyT
ntpp = prng_successor(nt, 32) ^ crypto1_word(pcs, 0, 0);
if (ntpp == BYTES4_TO_U32(answer)) {
// Successful verification!
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
} else {
// fail
return MF_ERR_AUTH;
return STATUS_MF_ERR_AUTH;
}
}
// fail!
return MF_ERR_AUTH;
return STATUS_MF_ERR_AUTH;
}
/**
@@ -279,15 +279,15 @@ static uint8_t darkside_select_nonces(picc_14a_tag_t *tag, uint8_t block, uint8_
// 2. Moderate power -off time, don't be too long, it will affect efficiency, and don't be too short.
reset_radio_field_with_delay();
// After the power is completely disconnected, we will select the card quickly and compress the verification time as much as possible.
if (pcd_14a_reader_fast_select(tag) != HF_TAG_OK) {
if (pcd_14a_reader_fast_select(tag) != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Tag can't select!\n");
return HF_TAG_NO;
return STATUS_HF_TAG_NO;
}
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, tag_auth, 4, tag_resp, &len, U8ARR_BIT_LEN(tag_resp));
// After finding the card, start collecting random numbers
if (status != HF_TAG_OK || len != 32) {
if (status != STATUS_HF_TAG_OK || len != 32) {
NRF_LOG_INFO("Get nt failed.\n");
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
// Converted to the type of U32 and cache
nt_list[i] = bytes_to_num(tag_resp, 4);
@@ -321,14 +321,14 @@ static uint8_t darkside_select_nonces(picc_14a_tag_t *tag, uint8_t block, uint8_
if (max == 0) {
NRF_LOG_INFO("Can't sync nt.\n");
*darkside_status = DARKSIDE_CANT_FIX_NT;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
// NT is fixed successfully, the one with the highest number of times we take out
// NRF_LOG_INFO("Sync nt: %"PRIu32", max = %d\n", nt_list[m], max);
if (nt) *nt = nt_list[m]; // Only when the caller needs to get NT
*darkside_status = DARKSIDE_OK;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -374,10 +374,10 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
bool led_toggle = false;
// We need to confirm the use of a certain card first
if (pcd_14a_reader_scan_auto(p_tag_info) == HF_TAG_OK) {
if (pcd_14a_reader_scan_auto(p_tag_info) == STATUS_HF_TAG_OK) {
uid_cur = get_u32_tag_uid(p_tag_info);
} else {
return HF_TAG_NO;
return STATUS_HF_TAG_NO;
}
// Verification instructions need to add CRC16
@@ -401,7 +401,7 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
// Then you need to fix a random number that may appear
status = darkside_select_nonces(p_tag_info, targetBlk, targetTyp, &nt_ori, darkside_status);
if ((status != HF_TAG_OK) || (*darkside_status != DARKSIDE_OK)) {
if ((status != STATUS_HF_TAG_OK) || (*darkside_status != DARKSIDE_OK)) {
//The fixed random number failed, and the next step cannot be performed
return status;
}
@@ -414,7 +414,7 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
if (uid_ori != uid_cur) {
*darkside_status = DARKSIDE_TAG_CHANGED;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
}
// Always collect different NACK under a large cycle
@@ -437,17 +437,17 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
reset_radio_field_with_delay();
//After the power is completely disconnected, we will select the card quickly and compress the verification time as much as possible.
if (pcd_14a_reader_fast_select(p_tag_info) != HF_TAG_OK) {
if (pcd_14a_reader_fast_select(p_tag_info) != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Tag can't select!\n");
return HF_TAG_NO;
return STATUS_HF_TAG_NO;
}
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, tag_auth, 4, dat_recv, &len, U8ARR_BIT_LEN(dat_recv));
// After finding the card, start collecting random numbers
if (status != HF_TAG_OK || len != 32) {
if (status != STATUS_HF_TAG_OK || len != 32) {
NRF_LOG_INFO("Get nt failed.\n");
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
//The byte array of the conversion response is 10 in NT
@@ -462,7 +462,7 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
if (++resync_count == ntSyncMax) {
NRF_LOG_INFO("Can't fix nonce.");
*darkside_status = DARKSIDE_CANT_FIX_NT;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
// When the clock is not synchronized, the following operation is meaningless
@@ -500,7 +500,7 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
// however we dont feed key w uid it the prng..
NRF_LOG_INFO("Auth Ok, you are so lucky!\n");
*darkside_status = DARKSIDE_LUCKY_AUTH_OK;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
@@ -529,7 +529,7 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
if (par == 0) { // tried all 256 possible parities without success. Card doesn't send NACK.
NRF_LOG_INFO("Card doesn't send NACK.\r\n");
*darkside_status = DARKSIDE_NO_NAK_SENT;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
} else {
par = ((par + 1) & 0x1F) | par_low;
@@ -555,7 +555,7 @@ uint8_t darkside_recover_key(uint8_t targetBlk, uint8_t targetTyp,
// NRF_LOG_INFO("Darkside done!\n");
*darkside_status = DARKSIDE_OK;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -587,19 +587,19 @@ uint8_t check_tag_response_nt(picc_14a_tag_t *tag, uint32_t *nt) {
pcd_14a_reader_halt_tag();
// We will choose a fast card, and we will be compressed to verify as much as possible
if (pcd_14a_reader_fast_select(tag) != HF_TAG_OK) {
if (pcd_14a_reader_fast_select(tag) != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Tag can't select\r\n");
return HF_TAG_NO;
return STATUS_HF_TAG_NO;
}
// Send instructions and get NT return
*nt = send_cmd(pcs, AUTH_FIRST, PICC_AUTHENT1A, 0x03, &status, dat_recv, par_recv, U8ARR_BIT_LEN(dat_recv));
if (*nt != 32) {
// NRF_LOG_INFO("No 32 data recv on send_cmd: %d\n", *nt);
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
*nt = bytes_to_num(dat_recv, 4);
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -614,8 +614,8 @@ uint8_t check_std_mifare_nt_support(void) {
uint32_t nt1 = 0;
// Find card, search on the field
if (pcd_14a_reader_scan_auto(p_tag_info) != HF_TAG_OK) {
return HF_TAG_NO;
if (pcd_14a_reader_scan_auto(p_tag_info) != STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_NO;
}
// Get NT and return status
@@ -633,13 +633,13 @@ uint8_t check_static_prng(bool *is_static) {
uint8_t status;
// Find card, search on the field
if (pcd_14a_reader_scan_auto(p_tag_info) != HF_TAG_OK) {
return HF_TAG_NO;
if (pcd_14a_reader_scan_auto(p_tag_info) != STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_NO;
}
// Get NT in the first wave
status = check_tag_response_nt(p_tag_info, &nt1);
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
return status;
}
@@ -650,13 +650,13 @@ uint8_t check_static_prng(bool *is_static) {
// Get NT in the second wave
status = check_tag_response_nt(p_tag_info, &nt2);
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
return status;
}
// Detect whether the random number is static
*is_static = (nt1 == nt2);
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -673,12 +673,12 @@ uint8_t check_prng_type(mf1_prng_type_t *prng_type) {
// If the judgment process is found, it is found that the StaticNested detection cannot be completed
// Then return the state directly, no need to perform the following judgment logic.
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
return status;
}
if (is_static) {
*prng_type = PRNG_STATIC;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
// Non -Static card, you can continue to run down logic
@@ -689,13 +689,13 @@ uint8_t check_prng_type(mf1_prng_type_t *prng_type) {
pcd_14a_reader_halt_tag();
// Card search operation
if (pcd_14a_reader_scan_auto(p_tag_info) != HF_TAG_OK) {
return HF_TAG_NO;
if (pcd_14a_reader_scan_auto(p_tag_info) != STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_NO;
}
//Get NT, just get it once
status = check_tag_response_nt(p_tag_info, &nt1);
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
return status;
}
@@ -712,7 +712,7 @@ uint8_t check_prng_type(mf1_prng_type_t *prng_type) {
// ------------------------------------
// end
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -785,19 +785,19 @@ static uint8_t measure_distance(uint64_t u64Key, uint8_t block, uint8_t type, ui
// Reset card communication
pcd_14a_reader_halt_tag();
// We will choose a fast card, and we will be compressed to verify as much as possible
if (pcd_14a_reader_fast_select(p_tag_info) != HF_TAG_OK) {
if (pcd_14a_reader_fast_select(p_tag_info) != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Tag can't select\r\n");
return HF_TAG_NO;
return STATUS_HF_TAG_NO;
}
// Perform the first verification in order to obtain the unblocked NT1
if (authex(pcs, uid, block, type, u64Key, AUTH_FIRST, &nt1) != HF_TAG_OK) {
if (authex(pcs, uid, block, type, u64Key, AUTH_FIRST, &nt1) != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Auth failed 1\r\n");
return MF_ERR_AUTH;
return STATUS_MF_ERR_AUTH;
}
// Met the nested verification to obtain the encrypted NT2_ENC
if (authex(pcs, uid, block, type, u64Key, AUTH_NESTED, &nt2) != HF_TAG_OK) {
if (authex(pcs, uid, block, type, u64Key, AUTH_NESTED, &nt2) != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Auth failed 2\r\n");
return MF_ERR_AUTH;
return STATUS_MF_ERR_AUTH;
}
// Determine whether the two random numbers are the same, under normal circumstances,
// We can't bring the same random number, because PRNG is updating chip at any time
@@ -805,7 +805,7 @@ static uint8_t measure_distance(uint64_t u64Key, uint8_t block, uint8_t type, ui
if (nt1 == nt2) {
NRF_LOG_INFO("StaticNested: %08x vs %08x\n", nt1, nt2);
*distance = 0;
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
// After the measurement is completed, store in the buffer
distances[index++] = measure_nonces(nt1, nt2);
@@ -815,7 +815,7 @@ static uint8_t measure_distance(uint64_t u64Key, uint8_t block, uint8_t type, ui
//The final calculation of the distance between the two NTs and spread it directly
*distance = measure_median(distances, DIST_NR);
// You need to return the OK value to successfully log in
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -841,16 +841,16 @@ static uint8_t nested_recover_core(mf1_nested_core_t *pnc, uint64_t keyKnown, ui
// Reset card communication
pcd_14a_reader_halt_tag();
// Quickly select the card to complete the verification steps to collect NT1 and NT2_ENC
if (pcd_14a_reader_scan_auto(p_tag_info) != HF_TAG_OK) {
return HF_TAG_NO;
if (pcd_14a_reader_scan_auto(p_tag_info) != STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_NO;
}
//The first step verification, basic verification does not require nested and encrypted
if (authex(pcs, uid, blkKnown, typKnown, keyKnown, AUTH_FIRST, &nt1) != HF_TAG_OK) {
return MF_ERR_AUTH;
if (authex(pcs, uid, blkKnown, typKnown, keyKnown, AUTH_FIRST, &nt1) != STATUS_HF_TAG_OK) {
return STATUS_MF_ERR_AUTH;
}
// Then there is nested verification
if (send_cmd(pcs, AUTH_NESTED, targetType, targetBlock, &status, answer, parity, U8ARR_BIT_LEN(answer)) != 32) {
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
};
// The first verified explicitly random number
num_to_bytes(nt1, 4, pnc->nt1);
@@ -861,7 +861,7 @@ static uint8_t nested_recover_core(mf1_nested_core_t *pnc, uint64_t keyKnown, ui
pnc->par |= ((oddparity8(answer[0]) != parity[0]) << 0);
pnc->par |= ((oddparity8(answer[1]) != parity[1]) << 1);
pnc->par |= ((oddparity8(answer[2]) != parity[2]) << 2);
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -872,14 +872,14 @@ static uint8_t nested_recover_core(mf1_nested_core_t *pnc, uint64_t keyKnown, ui
* @param :targetBlock : The target sector that requires a Nested attack
* @param :targetType : The target key type requires the Nested attack
* @param :ncs : Nested core structure array, save related communication data
* @retval :The attack success return HF_TAG_OK, else return the error code
* @retval :The attack success return STATUS_HF_TAG_OK, else return the error code
*
*/
uint8_t nested_recover_key(uint64_t keyKnown, uint8_t blkKnown, uint8_t typKnown, uint8_t targetBlock, uint8_t targetType, mf1_nested_core_t ncs[SETS_NR]) {
uint8_t m, res;
// all operations must be based on the card
res = pcd_14a_reader_scan_auto(p_tag_info);
if (res != HF_TAG_OK) {
if (res != STATUS_HF_TAG_OK) {
return res;
}
//Then collect the specified number of random array
@@ -892,11 +892,11 @@ uint8_t nested_recover_key(uint64_t keyKnown, uint8_t blkKnown, uint8_t typKnown
targetBlock,
targetType
);
if (res != HF_TAG_OK) {
if (res != STATUS_HF_TAG_OK) {
return res;
}
}
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -909,11 +909,11 @@ uint8_t nested_recover_key(uint64_t keyKnown, uint8_t blkKnown, uint8_t typKnown
*
*/
uint8_t nested_distance_detect(uint8_t block, uint8_t type, uint8_t *key, uint8_t *uid, uint32_t *distance) {
uint8_t status = HF_TAG_OK;
uint8_t status = STATUS_HF_TAG_OK;
*distance = 0;
//Must ensure that there is a card on the court
status = pcd_14a_reader_scan_auto(p_tag_info);
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
return status;
} else {
// At least the card exists, you can copy the UID to the buffer first
@@ -934,7 +934,7 @@ uint8_t nested_distance_detect(uint8_t block, uint8_t type, uint8_t *key, uint8_
* @param :targetBlock : Target sectors that require nested attacks
* @param :targetType : Target key types that require nested attacks
* @param :nestedAgain : StaticNested enhanced vulnerability, which can obtain two sets of encrypted random numbers based on nested verification of known keys
* @retval : Successfully collected and returned to HF_TAG_OK, otherwise an error code will be returned.
* @retval : Successfully collected and returned to STATUS_HF_TAG_OK, otherwise an error code will be returned.
*
*/
uint8_t static_nested_recover_core(uint8_t *p_nt1, uint8_t *p_nt2, uint64_t keyKnown, uint8_t blkKnown, uint8_t typKnown, uint8_t targetBlock, uint8_t targetType, uint8_t nestedAgain) {
@@ -946,28 +946,28 @@ uint8_t static_nested_recover_core(uint8_t *p_nt1, uint8_t *p_nt2, uint64_t keyK
uint32_t uid, nt1, nt2;
uid = get_u32_tag_uid(p_tag_info);
pcd_14a_reader_halt_tag();
if (pcd_14a_reader_fast_select(p_tag_info) != HF_TAG_OK) {
return HF_TAG_NO;
if (pcd_14a_reader_fast_select(p_tag_info) != STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_NO;
}
status = authex(pcs, uid, blkKnown, typKnown, keyKnown, AUTH_FIRST, &nt1);
if (status != HF_TAG_OK) {
return MF_ERR_AUTH;
if (status != STATUS_HF_TAG_OK) {
return STATUS_MF_ERR_AUTH;
}
if (nestedAgain) {
status = authex(pcs, uid, blkKnown, typKnown, keyKnown, AUTH_NESTED, NULL);
if (status != HF_TAG_OK) {
return MF_ERR_AUTH;
if (status != STATUS_HF_TAG_OK) {
return STATUS_MF_ERR_AUTH;
}
}
len = send_cmd(pcs, AUTH_NESTED, targetType, targetBlock, &status, answer, parity, U8ARR_BIT_LEN(answer));
if (len != 32) {
NRF_LOG_INFO("No 32 data recv on sendcmd: %d\r\n", len);
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
nt2 = bytes_to_num(answer, 4);
num_to_bytes(nt1, 4, p_nt1);
num_to_bytes(nt2, 4, p_nt2);
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -979,25 +979,25 @@ uint8_t static_nested_recover_core(uint8_t *p_nt1, uint8_t *p_nt2, uint64_t keyK
* @param :targetBlock : Target sectors that require nested attacks
* @param :targetType : Target key type that require nested attacks
* @param :sncs : StaticNested Decrypting Core Structure Array
* @retval : Successfully collected and returned to HF_TAG_OK, otherwise an error code will be returned.
* @retval : Successfully collected and returned to STATUS_HF_TAG_OK, otherwise an error code will be returned.
*
*/
uint8_t static_nested_recover_key(uint64_t keyKnown, uint8_t blkKnown, uint8_t typKnown, uint8_t targetBlock, uint8_t targetType, mf1_static_nested_core_t *sncs) {
uint8_t res;
res = pcd_14a_reader_scan_auto(p_tag_info);
if (res != HF_TAG_OK) {
if (res != STATUS_HF_TAG_OK) {
return res;
}
get_4byte_tag_uid(p_tag_info, sncs->uid);
res = static_nested_recover_core(sncs->core[0].nt1, sncs->core[0].nt2, keyKnown, blkKnown, typKnown, targetBlock, targetType, false);
if (res != HF_TAG_OK) {
if (res != STATUS_HF_TAG_OK) {
return res;
}
res = static_nested_recover_core(sncs->core[1].nt1, sncs->core[1].nt2, keyKnown, blkKnown, typKnown, targetBlock, targetType, true);
if (res != HF_TAG_OK) {
if (res != STATUS_HF_TAG_OK) {
return res;
}
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -1007,8 +1007,8 @@ uint8_t static_nested_recover_key(uint64_t keyKnown, uint8_t blkKnown, uint8_t t
*/
uint8_t auth_key_use_522_hw(uint8_t block, uint8_t type, uint8_t *key) {
// Each verification of a block must re -find a card
if (pcd_14a_reader_scan_auto(p_tag_info) != HF_TAG_OK) {
return HF_TAG_NO;
if (pcd_14a_reader_scan_auto(p_tag_info) != STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_NO;
}
// After finding the card, we start to verify!
return pcd_14a_reader_mf1_auth(p_tag_info, type, block, key);
+87 -81
View File
@@ -257,7 +257,7 @@ uint16_t pcd_14a_reader_timeout_get() {
* @retval : Status value mi_ok, successful
*/
uint8_t pcd_14a_reader_bytes_transfer(uint8_t Command, uint8_t *pIn, uint8_t InLenByte, uint8_t *pOut, uint16_t *pOutLenBit, uint16_t maxOutLenBit) {
uint8_t status = HF_ERR_STAT;
uint8_t status = STATUS_HF_ERR_STAT;
uint8_t waitFor = 0x00;
uint8_t lastBits = 0;
uint8_t n = 0;
@@ -290,7 +290,7 @@ uint8_t pcd_14a_reader_bytes_transfer(uint8_t Command, uint8_t *pIn, uint8_t In
if (pOut == NULL) {
// If the developer does not need to receive data, then return directly after the sending!
while ((read_register_single(Status2Reg) & 0x07) == 0x03);
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
bsp_set_timer(g_timeout_auto_timer, 0); // Before starting the operation, return to zero over time counting
@@ -316,24 +316,24 @@ uint8_t pcd_14a_reader_bytes_transfer(uint8_t Command, uint8_t *pIn, uint8_t In
if (pcd_err_val & 0x01) { // ProtocolErr Error only appears in the following two cases:
if (Command == PCD_AUTHENT) { // During the execution of the MFAUTHENT command, if the number of bytes received by a data stream, the position of the place
// Therefore, we need to deal with it well, assuming that there are problems during the verification process, then we need to think that this is normal
status = MF_ERR_AUTH;
status = STATUS_MF_ERR_AUTH;
} else { // If the SOF is wrong, the position is set up and the receiver is automatically cleared during the start -up stage, which is effective at the rate of 106kbd
NRF_LOG_INFO("Protocol error\n");
status = HF_ERR_STAT;
status = STATUS_HF_ERR_STAT;
}
} else if (pcd_err_val & 0x02) {
// Detecting whether there are even strange errors
NRF_LOG_INFO("Parity error\n");
status = HF_ERR_PARITY;
status = STATUS_HF_ERR_PARITY;
} else if (pcd_err_val & 0x04) { // Detect whether there are CRC errors
NRF_LOG_INFO("CRC error\n");
status = HF_ERR_CRC;
status = STATUS_HF_ERR_CRC;
} else if (pcd_err_val & 0x08) { // There is a conflict to detect the label
NRF_LOG_INFO("Collision tag\n");
status = HF_COLLISION;
status = STATUS_HF_COLLISION;
} else { // There are other unrepaired abnormalities
NRF_LOG_INFO("HF error: 0x%0x2\n", pcd_err_val);
status = HF_ERR_STAT;
status = STATUS_HF_ERR_STAT;
}
} else {
// Occasionally occur
@@ -351,25 +351,25 @@ uint8_t pcd_14a_reader_bytes_transfer(uint8_t Command, uint8_t *pIn, uint8_t In
// Read all the data in FIFO
read_register_buffer(FIFODataReg, pOut, n);
// Transmission instructions can be considered success when reading normal data!
status = HF_TAG_OK;
status = STATUS_HF_TAG_OK;
} else {
NRF_LOG_INFO("pcd_14a_reader_bytes_transfer receive response overflow: %d, max = %d\n", *pOutLenBit, maxOutLenBit);
// We can't pass the problem with problems, which is meaningless for the time being
*pOutLenBit = 0;
// Since there is a problem with the data, let's notify the upper layer and inform me
status = HF_ERR_STAT;
status = STATUS_HF_ERR_STAT;
}
} else {
// Non -transmitted instructions, the execution is completed without errors and considered success!
status = HF_TAG_OK;
status = STATUS_HF_TAG_OK;
}
}
} else {
status = HF_TAG_NO;
status = STATUS_HF_TAG_NO;
// NRF_LOG_INFO("Tag lost(timeout).\n");
}
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
// If there are certain operations,
// We may need to remove MFCrypto1On This register logo,
// Because it may be because of the error encryption communication caused by verification
@@ -445,7 +445,7 @@ uint8_t pcd_14a_reader_bits_transfer(uint8_t *pTx, uint16_t szTxBits, uint8_t *
clear_register_mask(MfRxReg, 0x10); // Enable Qiqi school inspection
// Simply judge the length of data transmission
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
// NRF_LOG_INFO("pcd_14a_reader_bytes_transfer error status: %d\n", status);
return status;
}
@@ -465,7 +465,7 @@ uint8_t pcd_14a_reader_bits_transfer(uint8_t *pTx, uint16_t szTxBits, uint8_t *
NRF_LOG_INFO("pcd_14a_reader_bits_transfer decode parity data overflow: %d, max = %d\n", *pRxLenBit, szRxLenBitMax);
// There must be an overflow here, and the length of the data that is valid is reset to avoid misjudgment from external calls.
*pRxLenBit = 0;
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
// The process of the separation and dissection process of the unprecedented verification and the data
@@ -479,25 +479,25 @@ uint8_t pcd_14a_reader_bits_transfer(uint8_t *pTx, uint16_t szTxBits, uint8_t *
pRxPar[i - 1] = (buffer[i] & (1 << (i - 1))) >> (i - 1);
}
}
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
* @brief : ISO14443-A Fast Select
* @param tagtag info buffer
* @retval if return HF_TAG_OKthe tag is selected.
* @retval if return STATUS_HF_TAG_OKthe tag is selected.
*/
uint8_t pcd_14a_reader_fast_select(picc_14a_tag_t *tag) {
uint8_t resp[5] = {0}; // theoretically. A usual RATS will be much smaller
uint8_t uid_resp[4] = {0};
uint8_t sak = 0x04; // cascade uid
uint8_t status = HF_TAG_OK;
uint8_t status = STATUS_HF_TAG_OK;
uint8_t cascade_level = 0;
uint16_t len;
// Wakeup
if (pcd_14a_reader_atqa_request(resp, NULL, U8ARR_BIT_LEN(resp)) != HF_TAG_OK) {
return HF_TAG_NO;
if (pcd_14a_reader_atqa_request(resp, NULL, U8ARR_BIT_LEN(resp)) != STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_NO;
}
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
@@ -523,9 +523,9 @@ uint8_t pcd_14a_reader_fast_select(picc_14a_tag_t *tag) {
crc_14a_append(sel_uid, 7); // calculate and add CRC
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, sel_uid, sizeof(sel_uid), resp, &len, U8ARR_BIT_LEN(resp));
// Receive the SAK
if (status != HF_TAG_OK || !len) {
if (status != STATUS_HF_TAG_OK || !len) {
// printf("SAK Err: %d, %d\r\n", status, recv_len);
return HF_TAG_NO;
return STATUS_HF_TAG_NO;
}
sak = resp[0];
@@ -539,7 +539,7 @@ uint8_t pcd_14a_reader_fast_select(picc_14a_tag_t *tag) {
uid_resp[2] = uid_resp[3];
}
}
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -558,9 +558,9 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) {
}
// wake
if (pcd_14a_reader_atqa_request(tag->atqa, NULL, U8ARR_BIT_LEN(tag->atqa)) != HF_TAG_OK) {
// NRF_LOG_INFO("pcd_14a_reader_atqa_request HF_TAG_NO\r\n");
return HF_TAG_NO;
if (pcd_14a_reader_atqa_request(tag->atqa, NULL, U8ARR_BIT_LEN(tag->atqa)) != STATUS_HF_TAG_OK) {
// NRF_LOG_INFO("pcd_14a_reader_atqa_request STATUS_HF_TAG_NO\r\n");
return STATUS_HF_TAG_NO;
}
uint8_t resp[DEF_FIFO_LENGTH] = {0}; // theoretically. A usual RATS will be much smaller
@@ -585,7 +585,7 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) {
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, sel_all, sizeof(sel_all), resp, &len, U8ARR_BIT_LEN(resp));
// There is a label collision, we need to solve the collision
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
// The collision still has to be collided. Do n't have this during the decryption process.
// So do not solve the collision for the time being, but directly inform the user that the user guarantees that there is only one card in the field
NRF_LOG_INFO("Err at tag collision.\n");
@@ -607,16 +607,16 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) {
uint8_t bcc = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate BCC
if (sel_uid[6] != bcc) {
NRF_LOG_INFO("BCC%d incorrect, got 0x%02x, expected 0x%02x\n", cascade_level, sel_uid[6], bcc);
return HF_ERR_BCC;
return STATUS_HF_ERR_BCC;
}
crc_14a_append(sel_uid, 7); // calculate and add CRC
// send 9x 70 Choose a card
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, sel_uid, sizeof(sel_uid), resp, &len, U8ARR_BIT_LEN(resp));
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Err at sak receive.\n");
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
// Sak received by buffer
@@ -645,27 +645,30 @@ uint8_t pcd_14a_reader_scan_once(picc_14a_tag_t *tag) {
// Tag supports 14443-4, sending RATS
uint16_t ats_size;
status = pcd_14a_reader_ats_request(tag->ats, &ats_size, 0xFF * 8);
ats_size -= 2; // size returned by pcd_14a_reader_ats_request includes CRC
if (ats_size > 254) {
NRF_LOG_INFO("Invalid ATS > 254!");
return HF_ERR_ATS;
}
tag->ats_len = ats_size;
// We do not validate ATS here as we want to report ATS as it is without breaking 14a scan
if (tag->ats[0] != ats_size - 1) {
NRF_LOG_INFO("Invalid ATS! First byte doesn't match received length");
// return HF_ERR_ATS;
}
if (status != HF_TAG_OK) {
NRF_LOG_INFO("ats status %d, length %d", status, ats_size);
if (status != STATUS_HF_TAG_OK) {
NRF_LOG_INFO("Tag SAK claimed to support ATS but tag NAKd RATS");
// return HF_ERR_ATS;
tag->ats_len = 0;
// return STATUS_HF_ERR_ATS;
} else {
ats_size -= 2; // size returned by pcd_14a_reader_ats_request includes CRC
if (ats_size > 254) {
NRF_LOG_INFO("Invalid ATS > 254!");
return STATUS_HF_ERR_ATS;
}
tag->ats_len = ats_size;
// We do not validate ATS here as we want to report ATS as it is without breaking 14a scan
if (tag->ats[0] != ats_size - 1) {
NRF_LOG_INFO("Invalid ATS! First byte doesn't match received length");
// return STATUS_HF_ERR_ATS;
}
}
/*
* FIXME: If there is an issue here, it will cause the label to lose its selected state.
* It is necessary to reselect the card after the issue occurs here.
*/
}
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -678,14 +681,14 @@ uint8_t pcd_14a_reader_scan_auto(picc_14a_tag_t *tag) {
// The first card search
status = pcd_14a_reader_scan_once(tag);
if (status == HF_TAG_OK) {
return HF_TAG_OK;
if (status == STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_OK;
}
// Second card search
status = pcd_14a_reader_scan_once(tag);
if (status == HF_TAG_OK) {
return HF_TAG_OK;
if (status == STATUS_HF_TAG_OK) {
return STATUS_HF_TAG_OK;
}
// More than the number of upper limits
@@ -704,16 +707,19 @@ uint8_t pcd_14a_reader_ats_request(uint8_t *pAts, uint16_t *szAts, uint16_t szAt
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, rats, sizeof(rats), pAts, szAts, szAtsBitMax);
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
*szAts = 0;
NRF_LOG_INFO("Err at ats receive.\n");
NRF_LOG_ERROR("ATS rx error: %d", status);
return status;
} else if (*szAts == 7 && pAts[0] == 0x4) { // tag replied with NAK
*szAts = 0;
return STATUS_HF_ERR_ATS;
}
// NRF_LOG_INFO("Length: %d\n", *szAts);
NRF_LOG_INFO("Received ATS length: %d\n", *szAts);
if (*szAts > 0) { *szAts = *szAts / 8; }
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -724,7 +730,7 @@ uint8_t pcd_14a_reader_ats_request(uint8_t *pAts, uint16_t *szAts, uint16_t szAt
uint8_t pcd_14a_reader_atqa_request(uint8_t *resp, uint8_t *resp_par, uint16_t resp_max_bit) {
uint16_t len = 0;
uint8_t retry = 0;
uint8_t status = HF_TAG_OK;
uint8_t status = STATUS_HF_TAG_OK;
uint8_t wupa[] = { PICC_REQALL }; // 0x26 - REQA 0x52 - WAKE-UP
// we may need several tries if we did send an unknown command or a wrong authentication before...
@@ -736,13 +742,13 @@ uint8_t pcd_14a_reader_atqa_request(uint8_t *resp, uint8_t *resp_par, uint16_t r
// normal ATQA It is 2 bytes, that is, 16bit,
// We need to judge whether the data received is correct
if (status == HF_TAG_OK && len == 16) {
if (status == STATUS_HF_TAG_OK && len == 16) {
// You can confirm that at least one 14A card exists in the current field
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
// No card
return HF_TAG_NO;
return STATUS_HF_TAG_NO;
}
/**
@@ -765,21 +771,21 @@ uint8_t pcd_14a_reader_gen1a_unlock(void) {
// Unlock the first step, send 7bit 0x40
unlock = PICC_MAGICWUPC1;
status = pcd_14a_reader_bits_transfer(&unlock, 7, NULL, recvbuf, NULL, &rx_length, U8ARR_BIT_LEN(recvbuf));
if (!(status == HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
if (!(status == STATUS_HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
NRF_LOG_INFO("UNLOCK(MAGICWUPC1) FAILED! Length: %d, Status: %02x\n", rx_length, status);
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
// Step in the second step, send a complete byte 0x43
unlock = PICC_MAGICWUPC2;
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, &unlock, 1, recvbuf, &rx_length, U8ARR_BIT_LEN(recvbuf));
if (!(status == HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
if (!(status == STATUS_HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
NRF_LOG_INFO("UNLOCK(MAGICWUPC2) FAILED! Length: %d, Status: %02x\n", rx_length, status);
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
// There is no problem with unlocking twice. We default this unlock operation successfully!
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -807,19 +813,19 @@ uint8_t pcd_14a_reader_gen1a_uplock(void) {
uint8_t recvbuf[1] = { 0x00 };
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, uplock_1, sizeof(uplock_1), recvbuf, &rx_length, U8ARR_BIT_LEN(recvbuf));
if (!(status == HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
if (!(status == STATUS_HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
NRF_LOG_INFO("UPLOCK1(UFUID) FAILED!\n");
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, uplock_2, sizeof(uplock_2), recvbuf, &rx_length, U8ARR_BIT_LEN(recvbuf));
if (!(status == HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
if (!(status == STATUS_HF_TAG_OK && rx_length == 4 && recvbuf[0] == 0x0A)) {
NRF_LOG_INFO("UPLOCK2(UFUID) FAILED!\n");
return HF_ERR_STAT;
return STATUS_HF_ERR_STAT;
}
// Successful card sealing
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
/**
@@ -830,7 +836,7 @@ uint8_t pcd_14a_reader_gen1a_uplock(void) {
* ucaddr: block address
* pKEY: password
* PSNR: Card serial number, 4 bytes
* @retval : The status value HF_TAG_OK is successful, tag_errauth fails, and other returns indicate some abnormalities related to communication errors!
* @retval : The status value STATUS_HF_TAG_OK is successful, tag_errauth fails, and other returns indicate some abnormalities related to communication errors!
*/
uint8_t pcd_14a_reader_mf1_auth(picc_14a_tag_t *tag, uint8_t type, uint8_t addr, uint8_t *pKey) {
uint8_t dat_buff[12] = { type, addr };
@@ -844,11 +850,11 @@ uint8_t pcd_14a_reader_mf1_auth(picc_14a_tag_t *tag, uint8_t type, uint8_t addr,
// In order to improve compatibility, we directly judge the implementation of the execution PCD_AUTHENT
// After the instruction, whether the communication plus position in Status2reg is placed.
if (read_register_single(Status2Reg) & 0x08) {
return HF_TAG_OK;
return STATUS_HF_TAG_OK;
}
// Other situations are considered failure!
return MF_ERR_AUTH;
return STATUS_MF_ERR_AUTH;
}
/**
@@ -875,14 +881,14 @@ uint8_t pcd_14a_reader_mf1_read_by_cmd(uint8_t cmd, uint8_t addr, uint8_t *p) {
crc_14a_append(dat_buff, 2);
// Then initiate communication
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, dat_buff, 4, dat_buff, &len, U8ARR_BIT_LEN(dat_buff));
if (status == HF_TAG_OK) {
if (status == STATUS_HF_TAG_OK) {
if (len == 0x90 /* 0x90 = 144bits */) {
// 16 -byte length CRC data, in order not to waste the CPU performance,
// We can let 522 Calculate
crc_14a_calculate(dat_buff, 16, crc_buff);
// Check the CRC to avoid data errors
if ((crc_buff[0] != dat_buff[16]) || (crc_buff[1] != dat_buff[17])) {
status = HF_ERR_CRC;
status = STATUS_HF_ERR_CRC;
}
// Although CRC After checking the problem, but we can still pass back
// Read the card data, because developers may have special usage
@@ -890,7 +896,7 @@ uint8_t pcd_14a_reader_mf1_read_by_cmd(uint8_t cmd, uint8_t addr, uint8_t *p) {
} else {
// The data passed back is wrong, which may be an environmental factors or cards that do not comply with specifications!
// Or the control bit affects reading!
status = HF_ERR_STAT;
status = STATUS_HF_ERR_STAT;
}
}
return status;
@@ -928,16 +934,16 @@ uint8_t pcd_14a_reader_mf1_write_by_cmd(uint8_t cmd, uint8_t addr, uint8_t *p) {
// Request to write a card, at this time, the card should reply to ACK
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, dat_buff, 4, dat_buff, &dat_len, U8ARR_BIT_LEN(dat_buff));
// The communication fails, the reason is returned directly
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
return status;
}
// The communication was successful, but the operation was rejected by the card!
if ((dat_len != 4) || ((dat_buff[0] & 0x0F) != 0x0A)) {
// NRF_LOG_INFO("1 status = %d, datalen = %d, data = %02x\n", status, dat_len, dat_buff[0]);
status = HF_ERR_STAT;
status = STATUS_HF_ERR_STAT;
}
// The communication was successful, the card accepted the card writing operation
if (status == HF_TAG_OK) {
if (status == STATUS_HF_TAG_OK) {
// 1. Copy data and calculate CRC
memcpy(dat_buff, p, 16);
crc_14a_calculate(dat_buff, 16, &dat_buff[16]);
@@ -948,14 +954,14 @@ uint8_t pcd_14a_reader_mf1_write_by_cmd(uint8_t cmd, uint8_t addr, uint8_t *p) {
// 2. Transfer the final card writing data to complete the writing card
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, dat_buff, 18, dat_buff, &dat_len, U8ARR_BIT_LEN(dat_buff));
// The communication fails, the reason is returned directly
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
return status;
}
// The communication is successful, we need to determine whether the card is successfully processed after receiving the data
// And reply ACK
if ((dat_len != 4) || ((dat_buff[0] & 0x0F) != 0x0A)) {
// NRF_LOG_INFO("2 status = %d, datalen = %d, data = %02x\n", status, dat_len, dat_buff[0]);
status = HF_ERR_STAT;
status = STATUS_HF_ERR_STAT;
}
}
return status;
@@ -983,7 +989,7 @@ uint8_t pcd_14a_reader_halt_tag(void) {
// Prepare the molding data directly, and calculate a ghost CRC
uint8_t data[] = { PICC_HALT, 0x00, 0x57, 0xCD };
status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, data, 4, data, &unLen, U8ARR_BIT_LEN(data));
return status == HF_TAG_NO && unLen == 0;
return status == STATUS_HF_TAG_NO && unLen == 0;
}
/**
@@ -1205,7 +1211,7 @@ inline void pcd_14a_reader_crc_computer(uint8_t use522CalcCRC) {
uint8_t pcd_14a_reader_raw_cmd(bool openRFField, bool waitResp, bool appendCrc, bool autoSelect, bool keepField, bool checkCrc, uint16_t waitRespTimeout,
uint16_t szDataSendBits, uint8_t *pDataSend, uint8_t *pDataRecv, uint16_t *pszDataRecv, uint16_t szDataRecvBitMax) {
// Status code, default is OK.
uint8_t status = HF_TAG_OK;
uint8_t status = STATUS_HF_TAG_OK;
// Reset recv length.
*pszDataRecv = 0;
@@ -1244,7 +1250,7 @@ uint8_t pcd_14a_reader_raw_cmd(bool openRFField, bool waitResp, bool appendCrc,
picc_14a_tag_t ti;
status = pcd_14a_reader_scan_once(&ti);
// Determine whether the card search was successful
if (status != HF_TAG_OK) {
if (status != STATUS_HF_TAG_OK) {
pcd_14a_reader_antenna_off();
return status;
}
@@ -1296,7 +1302,7 @@ uint8_t pcd_14a_reader_raw_cmd(bool openRFField, bool waitResp, bool appendCrc,
if (pDataRecv[finalRecvBytes - 2] != crc_buff[0] || pDataRecv[finalRecvBytes - 1] != crc_buff[1]) {
// We have found an error in CRC verification and need to inform the upper computer!
*pszDataRecv = 0;
status = HF_ERR_CRC;
status = STATUS_HF_ERR_CRC;
} else {
// If the CRC needs to be verified by the device and the device determines that the CRC is normal,
// we will return the data without CRC
@@ -19,9 +19,9 @@ uint32_t g_timeout_readem_ms = 500;
* Search EM410X tag
*/
uint8_t PcdScanEM410X(uint8_t *uid) {
uint8_t ret = EM410X_TAG_NO_FOUND;
uint8_t ret = STATUS_EM410X_TAG_NO_FOUND;
if (em410x_read(uid, g_timeout_readem_ms) == 1) {
ret = LF_TAG_OK;
ret = STATUS_LF_TAG_OK;
}
return ret;
}
@@ -32,8 +32,8 @@ uint8_t PcdScanEM410X(uint8_t *uid) {
uint8_t check_write_ok(uint8_t *uid, uint8_t *newuid, uint8_t on_uid_diff_return) {
// After the card is written, we need to read it once,
// If the data I read is incorrect, it means that the writing fails
if (PcdScanEM410X(newuid) != LF_TAG_OK) {
return EM410X_TAG_NO_FOUND;
if (PcdScanEM410X(newuid) != STATUS_LF_TAG_OK) {
return STATUS_EM410X_TAG_NO_FOUND;
}
// If you read the card number the same
// Explanation is successful (maybe)
@@ -43,7 +43,7 @@ uint8_t check_write_ok(uint8_t *uid, uint8_t *newuid, uint8_t on_uid_diff_return
uid[2] == newuid[2] &&
uid[3] == newuid[3] &&
uid[4] == newuid[4]) {
return LF_TAG_OK;
return STATUS_LF_TAG_OK;
}
// If you find the card, the card number is wrong,
// Then we will return the abnormal value of the inlet
@@ -102,7 +102,7 @@ uint8_t PcdWriteT55XX(uint8_t *uid, uint8_t *newkey, uint8_t *old_keys, uint8_t
// Read the verification and return the results of the card writing
// Do not read it here, you can check it by the upper machine
return LF_TAG_OK;
return STATUS_LF_TAG_OK;
}
/**
+1 -1
View File
@@ -137,7 +137,7 @@ uint8_t settings_save_config(void) {
NRF_LOG_INFO("Config did not change.");
}
return STATUS_DEVICE_SUCCESS;
return STATUS_SUCCESS;
}
uint8_t settings_get_animation_config() {
+1
View File
@@ -94,6 +94,7 @@ class ChameleonCLI:
raise Exception("This script requires at least Python 3.9")
self.print_banner()
chameleon_cli_unit.check_tools()
cmd_strs = []
while True:
if cmd_strs:
+22 -10
View File
@@ -15,11 +15,10 @@ from platform import uname
import chameleon_com
import chameleon_cmd
import chameleon_status
from chameleon_utils import ArgumentParserNoExit, ArgsParserError, UnexpectedResponseError
from chameleon_utils import CLITree
from chameleon_utils import CR, CG, CB, CC, CY, CM, C0
from chameleon_enum import Command, SlotNumber, TagSenseType, TagSpecificType
from chameleon_enum import Command, Status, SlotNumber, TagSenseType, TagSpecificType
from chameleon_enum import MifareClassicWriteMode, MifareClassicPrngType, MifareClassicDarksideStatus, MfcKeyType
from chameleon_enum import AnimationMode, ButtonType, ButtonPressFunction
@@ -37,12 +36,22 @@ type_id_SAK_dict = {0x00: "MIFARE Ultralight Classic/C/EV1/Nano | NTAG 2xx",
0x38: "SmartMX with MIFARE Classic 4K",
}
if getattr(sys, 'frozen', False):
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
# in pyinstaller
default_cwd = str(Path(sys._MEIPASS) / "bin")
default_cwd = Path.cwd() / Path(sys._MEIPASS) / "bin"
else:
# from source
default_cwd = str(Path(__file__).parent.parent / "bin")
default_cwd = Path.cwd() / Path(__file__).parent.parent / "bin"
def check_tools():
tools = ['staticnested', 'nested', 'darkside', 'mfkey32v2']
if sys.platform == "win32":
tools = [x+'.exe' for x in tools]
missing_tools = [tool for tool in tools if not (default_cwd / tool).exists()]
if len(missing_tools) > 0:
print(f'{CR}Warning, tools {", ".join(missing_tools)} not found. '
f'Corresponding commands will not work as intended.{C0}')
class BaseCLIUnit:
@@ -1990,11 +1999,14 @@ class HWRaw(DeviceRequiredUnit):
print(f" Command: {response.cmd} {command.name}")
except ValueError:
print(f" Command: {response.cmd} (unknown)")
status_string = f" Status: {response.status:#02x}"
if response.status in chameleon_status.Device:
status_string += f" {chameleon_status.Device[response.status]}"
if response.status in chameleon_status.message:
status_string += f": {chameleon_status.message[response.status]}"
try:
status = Status(response.status)
status_string += f" {status.name}"
status_string += f": {str(status)}"
except ValueError:
pass
print(status_string)
print(f" Data (HEX): {response.data.hex()}")
@@ -2037,7 +2049,7 @@ examples/notes:
def on_exec(self, args: argparse.Namespace):
options = {
'activate_rf_field': self.bool_to_bit(args.activate_rf),
'wait_response': self.bool_to_bit(not args.response),
'wait_response': self.bool_to_bit(not args.no_response),
'append_crc': self.bool_to_bit(args.crc),
'auto_select': self.bool_to_bit(args.select_tag),
'keep_rf_field': self.bool_to_bit(args.keep_rf),
File diff suppressed because it is too large Load Diff
+12 -8
View File
@@ -3,9 +3,8 @@ import struct
import threading
import time
import serial
import chameleon_status
from chameleon_utils import CR, CG, CB, CC, CY, CM, C0
from chameleon_enum import Command
from chameleon_enum import Command, Status
# each thread is waiting for its data for 100 ms before looping again
THREAD_BLOCKING_TIMEOUT = 0.1
@@ -201,13 +200,13 @@ class ChameleonCom:
command_string = f"{data_cmd} {command.name}"
except ValueError:
command_string = f"{data_cmd} (unknown)"
if data_status in chameleon_status.Device:
status_string = chameleon_status.Device[data_status]
if data_status == chameleon_status.Device.STATUS_DEVICE_SUCCESS:
try:
status_string = str(Status(data_status))
if data_status == Status.SUCCESS:
status_string = f'{CG}{status_string:30}{C0}'
else:
status_string = f'{CR}{status_string:30}{C0}'
else:
except ValueError:
status_string = f"{CR}{data_status:30x}{C0}"
print(f'<= {CC}{command_string:40}{C0}{status_string}'
f'{CY}{data_response.hex() if data_response is not None else ""}{C0}')
@@ -321,7 +320,12 @@ class ChameleonCom:
del self.wait_response_map[cmd]
# make data frame
if DEBUG:
cmd_string = f'{cmd:4} {cmd.name}{f"[{status:04x}]" if status != 0 else ""}'
try:
command = Command(cmd)
command_name = f"{command.name}"
except ValueError:
command_name = "(UNKNOWN)"
cmd_string = f'{cmd:4} {command_name}{f"[{status:04x}]" if status != 0 else ""}'
print(f'=> {CC}{cmd_string:40}{C0}'
f'{CY}{data.hex() if data is not None else ""}{C0}')
data_frame = self.make_data_frame_bytes(cmd, data, status)
@@ -361,7 +365,7 @@ class ChameleonCom:
# ok, data received.
data_response = self.wait_response_map[cmd]['response']
del self.wait_response_map[cmd]
if data_response.status == chameleon_status.Device.STATUS_INVALID_CMD:
if data_response.status == Status.INVALID_CMD:
raise CMDInvalidException(f"Device unsupported cmd: {cmd}")
return data_response
+68
View File
@@ -97,6 +97,74 @@ class Command(enum.IntEnum):
EM410X_GET_EMU_ID = 5001
@enum.unique
class Status(enum.IntEnum):
HF_TAG_OK = 0x00 # IC card operation is successful
HF_TAG_NO = 0x01 # IC card not found
HF_ERR_STAT = 0x02 # Abnormal IC card communication
HF_ERR_CRC = 0x03 # IC card communication verification abnormal
HF_COLLISION = 0x04 # IC card conflict
HF_ERR_BCC = 0x05 # IC card BCC error
MF_ERR_AUTH = 0x06 # MF card verification failed
HF_ERR_PARITY = 0x07 # IC card parity error
HF_ERR_ATS = 0x08 # ATS should be present but card NAKed, or ATS too large
# Some operations with low frequency cards succeeded!
LF_TAG_OK = 0x40
# Unable to search for a valid EM410X label
EM410X_TAG_NO_FOUND = 0x41
# The parameters passed by the BLE instruction are wrong, or the parameters passed
# by calling some functions are wrong
PAR_ERR = 0x60
# The mode of the current device is wrong, and the corresponding API cannot be called
DEVICE_MODE_ERROR = 0x66
INVALID_CMD = 0x67
SUCCESS = 0x68
NOT_IMPLEMENTED = 0x69
FLASH_WRITE_FAIL = 0x70
FLASH_READ_FAIL = 0x71
def __str__(self):
if self == Status.HF_TAG_OK:
return "HF tag operation succeeded"
elif self == Status.HF_TAG_NO:
return "HF tag no found or lost"
elif self == Status.HF_ERR_STAT:
return "HF tag status error"
elif self == Status.HF_ERR_CRC:
return "HF tag data crc error"
elif self == Status.HF_COLLISION:
return "HF tag collision"
elif self == Status.HF_ERR_BCC:
return "HF tag uid bcc error"
elif self == Status.MF_ERR_AUTH:
return "HF tag auth fail"
elif self == Status.HF_ERR_PARITY:
return "HF tag data parity error"
elif self == Status.HF_ERR_ATS:
return "HF tag was supposed to send ATS but didn't"
elif self == Status.LF_TAG_OK:
return "LF tag operation succeeded"
elif self == Status.EM410X_TAG_NO_FOUND:
return "EM410x tag no found"
elif self == Status.PAR_ERR:
return "API request fail, param error"
elif self == Status.DEVICE_MODE_ERROR:
return "API request fail, device mode error"
elif self == Status.INVALID_CMD:
return "API request fail, cmd invalid"
elif self == Status.SUCCESS:
return "Device operation succeeded"
elif self == Status.NOT_IMPLEMENTED:
return "Some api not implemented"
elif self == Status.FLASH_WRITE_FAIL:
return "Flash write failed"
elif self == Status.FLASH_READ_FAIL:
return "Flash read failed"
return "Invalid status"
@enum.unique
class SlotNumber(enum.IntEnum):
SLOT_1 = 1
-73
View File
@@ -1,73 +0,0 @@
class MetaDevice(type):
def __iter__(self):
for attr in dir(self):
if not attr.startswith("__"):
yield attr
def __contains__(self, item):
for field in self.__dict__:
val = self.__dict__[field]
if isinstance(val, int):
if val == item:
return True
return False
def __getitem__(self, item):
for field in self.__dict__:
val = self.__dict__[field]
if isinstance(val, int):
if val == item:
return field
return False
class Device(metaclass=MetaDevice):
HF_TAG_OK = 0x00 # IC card operation is successful
HF_TAG_NO = 0x01 # IC card not found
HF_ERR_STAT = 0x02 # Abnormal IC card communication
HF_ERR_CRC = 0x03 # IC card communication verification abnormal
HF_COLLISION = 0x04 # IC card conflict
HF_ERR_BCC = 0x05 # IC card BCC error
MF_ERR_AUTH = 0x06 # MF card verification failed
HF_ERR_PARITY = 0x07 # IC card parity error
HF_ERR_ATS = 0x08 # ATS should be present but card NAKed, or ATS too large
# Some operations with low frequency cards succeeded!
LF_TAG_OK = 0x40
# Unable to search for a valid EM410X label
EM410X_TAG_NO_FOUND = 0x41
# The parameters passed by the BLE instruction are wrong, or the parameters passed
# by calling some functions are wrong
STATUS_PAR_ERR = 0x60
# The mode of the current device is wrong, and the corresponding API cannot be called
STATUS_DEVICE_MODE_ERROR = 0x66
STATUS_INVALID_CMD = 0x67
STATUS_DEVICE_SUCCESS = 0x68
STATUS_NOT_IMPLEMENTED = 0x69
STATUS_FLASH_WRITE_FAIL = 0x70
STATUS_FLASH_READ_FAIL = 0x71
message = {
Device.HF_TAG_OK: "HF tag operation succeeded",
Device.HF_TAG_NO: "HF tag no found or lost",
Device.HF_ERR_STAT: "HF tag status error",
Device.HF_ERR_CRC: "HF tag data crc error",
Device.HF_COLLISION: "HF tag collision",
Device.HF_ERR_BCC: "HF tag uid bcc error",
Device.MF_ERR_AUTH: "HF tag auth fail",
Device.HF_ERR_PARITY: "HF tag data parity error",
Device.HF_ERR_ATS: "HF tag was supposed to send ATS but didn't",
Device.LF_TAG_OK: "LF tag operation succeeded",
Device.EM410X_TAG_NO_FOUND: "EM410x tag no found",
Device.STATUS_PAR_ERR: "API request fail, param error",
Device.STATUS_DEVICE_MODE_ERROR: "API request fail, device mode error",
Device.STATUS_INVALID_CMD: "API request fail, cmd invalid",
Device.STATUS_DEVICE_SUCCESS: "Device operation succeeded",
Device.STATUS_NOT_IMPLEMENTED: "Some api not implemented",
Device.STATUS_FLASH_WRITE_FAIL: "Flash write failed",
Device.STATUS_FLASH_READ_FAIL: "Flash read failed"
}
+6 -7
View File
@@ -6,7 +6,7 @@ from prompt_toolkit.completion import Completer, NestedCompleter, WordCompleter
from prompt_toolkit.completion.base import Completion
from prompt_toolkit.document import Document
import chameleon_status
from chameleon_enum import Status
# Colorama shorthands
CR = colorama.Fore.RED
@@ -110,12 +110,11 @@ def expect_response(accepted_responses: Union[int, list[int]]):
def error_throwing_func(*args, **kwargs):
ret = func(*args, **kwargs)
if ret.status not in accepted_responses:
if ret.status in chameleon_status.Device and ret.status in chameleon_status.message:
raise UnexpectedResponseError(
chameleon_status.message[ret.status])
else:
raise UnexpectedResponseError(
f"Unexpected response and unknown status {ret.status}")
try:
status_string = str(Status(ret.status))
except ValueError:
status_string = f"Unexpected response and unknown status {ret.status}"
raise UnexpectedResponseError(status_string)
return ret.data