Merge remote-tracking branch 'origin/main' into cli-overhaul

This commit is contained in:
Szymon Borecki
2023-08-19 14:19:40 +02:00
34 changed files with 1123 additions and 401 deletions
+22 -39
View File
@@ -76,7 +76,8 @@ jobs:
name: ${{ matrix.device_type }}-dfu-full
path: firmware/objects/dfu-full/*
create_release:
permissions: write-all
permissions:
contents: write
name: Create Pre-Release with dfu app images
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
@@ -85,52 +86,34 @@ jobs:
steps:
- name: Check out the repo
uses: actions/checkout@v3
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.run_number }}
release_name: Compiled commit ${{ github.sha }}
body: |
Auto-Generated DFU images
draft: false
prerelease: true
- name: Download Ultra DFU
uses: actions/download-artifact@v3
with:
name: ultra-dfu-app
path: dfu-app-artifacts
- name: Compress
path: ultra-dfu-app
- name: Compress Ultra DFU package
run: |
zip --junk-paths -0 -r ./dfu-app-artifacts/dfu-app.zip ./dfu-app-artifacts/*
- name: Upload Ultra DFU
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dfu-app-artifacts/dfu-app.zip
asset_name: ultra-dfu-app.zip
asset_content_type: application/zip
- name: Clear
run: |
rm -rf ./dfu-app-artifacts/
zip --junk-paths -0 -r ./ultra-dfu-app.zip ./ultra-dfu-app/*
- name: Download Lite DFU
uses: actions/download-artifact@v3
with:
name: lite-dfu-app
path: dfu-app-artifacts
- name: Compress
path: lite-dfu-app
- name: Compress Lite DFU package
run: |
zip --junk-paths -0 -r ./dfu-app-artifacts/dfu-app.zip ./dfu-app-artifacts/*
- name: Upload Lite DFU
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
zip --junk-paths -0 -r ./lite-dfu-app.zip ./lite-dfu-app/*
- name: Upload to dev release
uses: softprops/action-gh-release@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./dfu-app-artifacts/dfu-app.zip
asset_name: lite-dfu-app.zip
asset_content_type: application/zip
body: |
Auto-Generated DFU packages from latest `main` commit.
For development purposes only.
These are not tested, here be dragons.
Built from commit ${{ github.sha }}
tag_name: dev
name: Development release
draft: false
prerelease: true
target_commitish: main
generate_release_notes: true
files: ./*-dfu-app.zip
+3 -1
View File
@@ -1,3 +1,5 @@
.idea/
.vscode/
.vs/
.vs/
.DS_Store
+11
View File
@@ -309,3 +309,14 @@ in a second terminal:
```
JLinkRTTClient
```
## Using SWO pin as UART to monitor NRF_LOG
One can set `NRF_LOG_UART_ON_SWO_ENABLED := 1` in `Makefile.defs` to activate this functionality.
When activated, NRF_LOG will be available if one connects a UART bridge to the SWO pin which will work as a UART TX pin.
UART works at 115200 bauds. E.g. one can use a FTDI dongle and `screen /dev/ttyUSB0 115200`.
Contrary to RTT that needs to be activated by a JTAG probe, UART logs are immediately available.
Limitations:
* SWO pin is shared with... SWO so when e.g. reflashing the device, garbage may appear on the monitoring terminal.
* SWO pin is also shared with the blue channel of the RGB slot LEDs, so faint blue may appear briefly when logs are sent and LED might not work properly when supposed to be blue.
+19 -219
View File
@@ -1,20 +1,32 @@
[nrf52_nfc_module_doc]: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fnfc.html
[tech_white_paper]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/Technical_White_Paper.md
[how_use_firmware]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/How_to_use_Firmware.md
[go_to_buy_lab401]: https://lab401.com/
[go_to_buy_hackerwarehouse]: https://hackerwarehouse.com/
[go_to_buy_sneaktechnology]: https://sneaktechnology.com
[go_to_buy_proxgrind_aliexpress]: https://proxgrind.aliexpress.com/store/1101312023
[nxp_rc522_datasheet]: https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
![alt text](https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Header.png)
# ChameleonUltra Authorised Distributors
Europe: [Lab401](https://lab401.com/)
Europe: [Lab401][go_to_buy_lab401]
United States: [Hackerwarehouse](https://hackerwarehouse.com/)
United States: [Hackerwarehouse][go_to_buy_hackerwarehouse]
Anywhere else: [Sneaktechnology](https://sneaktechnology.com) / [Aliexpress by RRG](https://proxgrind.aliexpress.com/store/1101312023)
Anywhere else: [Sneaktechnology][go_to_buy_sneaktechnology] / [Aliexpress by RRG][go_to_buy_proxgrind_aliexpress]
# How to use ?
Coming Soon.
- ChameleonUltra: [Technical White Paper][tech_white_paper] (Old content of this readme in here)
- ChameleonUltra: [Firmware][how_use_firmware]
More Coming Soon.
# Videos to reference
@@ -27,221 +39,9 @@ Downloading a GUI
https://www.youtube.com/watch?v=rHH7iqbX3nY
Link to the GUI
https://github.com/GameTec-live/ChameleonUltraGUI
# ChameleonUltra
Why not keep using ATxmega128?
First of all, it is difficult to buy chips because the lead time for the main chip is too long, and because the price
has skyrocketed. Secondly, because the interaction speed of the ATxmega simulation is slow, the decryption performance
of the READER mode cannot meet the needs, and the low-frequency function cannot be added, so we have been trying to
upgrade it, such as using the latest ARM to replace the AVR framework, and the performance will definitely be greatly
improved.
# Why NRF52840?
NRF52840 has a built-in NFC Tag-A module, but no one seems to care about it. After playing with HydraNFC's TRF7970A and
FlipperZero's ST25R3916, ~~the developers found that they can only simulate MIFARE UID~~. I accidentally tested the NFC of
52840, and found that it is not only surprisingly easy to simulate a complete MIFARE card, but also has very good
simulation performance, friendly data flow interaction, and very fast response, unlike the former which is limited by
the SPI bus clock rate. We also found that it has ultra-low power consumption, ultra-small size, 256kb/1M large RAM and
FLASH, also has BLE5.0 and USB2.0 FS, super CotexM4F, most importantly, he is very cheap! This is undoubtedly a treasure
discovery for us!
Below we will explain in detail how we exploited the performance of the NRF52840, and what seemingly impossible
functions have been realized with it!
**Update**:
* FlipperZero can simulate mifare sector now, but FDT so high.
# Supported functions
## High Frequency Attack
| Attack Type | Tag Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------|:-------------:|------------------------------:|---------------------------|:--------------------------------------:|------------------------:|
| Sniffing | No | No | No | No | |
| MFKEY32 V2 | MifareClassic | Support | Support | Support | MifareClassic Detection |
| Darkside | MifareClassic | Support | Support | Support | Encrypted 4 bit NAck |
| Nested | MifareClassic | Support | Support | Support | PRNG(Distance guess) |
| StaticNested | MifareClassic | Support | Support | Not yet implemented | PRNG(2NT Fast Decrypt) |
| HardNested | MifareClassic | Support | Support | Not yet implemented | No |
| Relay attack | ISO14443A | Support | Support | Not yet implemented | No |
## High Frequency Simulation
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|-------------------------------|:--------------------:|------------------------------:|---------------------------|:--------------------------------------:|-----------------------------------------:|
| Non <13.56MHz or ISO14443A> | No | No | No | No | [NRF52 NFC Module][nrf52_nfc_module_doc] |
| NTAG 21x (210-218) | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight Ev1 | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight C | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| MifareClassic1K/2K/4K (4B/7B) | ISO14443A/106 kbit/s | Support | Support | Support | |
| Mifare DESFire | ISO14443A High Rate | Only supported Low rate | Only supported Low rate | Not yet implemented | |
| Mifare DESFire EV1 | ISO14443A High rate | Only supported Low rate | Only supported Low rate | Not yet implemented | Backward compatible |
| Mifare DESFire EV2 | ISO14443A High rate | Only supported Low rate | Only supported Low rate | Not yet implemented | |
| Mifare PLUS | ISO14443A High rate | Only supported Low rate | Only supported Low rate | Not yet implemented | |
## High Frequency Reader
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|-------------------------------|:--------------------:|---------------------------------------------:|----------------------------------------------|:--------------------------------------:|-------------------------------------------:|
| Non <13.56MHz or ISO14443A> | No | No | No | No | [NXP RC522 Datasheet][nxp_rc522_datasheet] |
| NTAG 21x (210-218) | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight Ev1 | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight C | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| MifareClassic1K/2K/4K (4B/7B) | ISO14443A/106 kbit/s | Support | Support | Support | |
| Mifare DESFire | ISO14443A High Rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | |
| Mifare DESFire EV1 | ISO14443A High rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | Backward compatible |
| Mifare DESFire EV2 | ISO14443A High rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | |
| Mifare PLUS | ISO14443A High rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | |
## Low Frequency Attack
| Vulnerability Type | Tag Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------------|:---------:|------------------------------:|---------------------------|:--------------------------------------:|-----:|
| Sniffing | 125KHz | Support | Support | Not yet implemented | |
| Brute Force | EM410x ID | Support | Support | Not yet implemented | |
## Low Frequency Simulation
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------------------|:-------------:|------------------------------:|---------------------------|:--------------------------------------:|----------------------------------------------:|
| Non <125KHz/ASK/PSK/FSK> | No | No | No | No | Only 125 khz RF, Modulation ASK, FSK and PSK. |
| EM410x | ASK | Support | Support | Support | EM4100 is support(AD 64bit) |
| T5577 | ASK | Support | Support | Not yet implemented | |
| HID Prox | FSK | Support | Support | Not yet implemented | |
| Indala | PSK | Support | Support | Not yet implemented | |
| FDX-B | ASK | Support | Support | Not yet implemented | |
| Paradox | FSK | Support | Support | Not yet implemented | |
| Keri | PSK | Support | Support | Not yet implemented | |
| AWD | FSK | Support | Support | Not yet implemented | |
| ioProx | FSK | Support | Support | Not yet implemented | |
| securakey | ASK | Support | Support | Not yet implemented | |
| gallagher | ASK | Support | Support | Not yet implemented | |
| PAC/Stanley | ASK | Support | Support | Not yet implemented | |
| Presco | ASK | Support | Support | Not yet implemented | |
| Visa2000 | ASK | Support | Support | Not yet implemented | |
| Viking | ASK | Support | Support | Not yet implemented | |
| Noralsy | ASK | Support | Support | Not yet implemented | |
| NexWatch | PSK | Support | Support | Not yet implemented | |
| Jablotron | ASK | Support | Support | Not yet implemented | |
## Low Frequency Reader
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------------------|:-------------:|------------------------------:|---------------------------|:--------------------------------------:|----------------------------------------------:|
| Non <125KHz/ASK/PSK/FSK> | No | No | No | No | Only 125 khz RF, Modulation ASK, FSK and PSK. |
| EM410x | ASK | Support | Support | Support | |
| T5577 | ASK | Support | Support | Support(Write) | |
| HID Prox | FSK | Support | Support | Not yet implemented | |
| Indala | PSK | Support | Support | Not yet implemented | |
| FDX-B | ASK | Support | Support | Not yet implemented | |
| Paradox | FSK | Support | Support | Not yet implemented | |
| Keri | PSK | Support | Support | Not yet implemented | |
| AWD | FSK | Support | Support | Not yet implemented | |
| ioProx | FSK | Support | Support | Not yet implemented | |
| securakey | ASK | Support | Support | Not yet implemented | |
| gallagher | ASK | Support | Support | Not yet implemented | |
| PAC/Stanley | ASK | Support | Support | Not yet implemented | |
| Presco | ASK | Support | Support | Not yet implemented | |
| Visa2000 | ASK | Support | Support | Not yet implemented | |
| Viking | ASK | Support | Support | Not yet implemented | |
| Noralsy | ASK | Support | Support | Not yet implemented | |
| NexWatch | PSK | Support | Support | Not yet implemented | |
| Jablotron | ASK | Support | Support | Not yet implemented | |
## Low Frequency Modulation
[modulation_psk]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/PSK.png
[modulation_fsk]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/FSK.png
[modulation_ask]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/ASK.png
| Modulation Type | wav |
|-----------------|----------------------------:|
| PSK | ![alt text][modulation_psk] |
| FSK | ![alt text][modulation_fsk] |
| ASK | ![alt text][modulation_ask] |
# 1. Ultra-low power consumption
It integrates a high-performance and low-power NFC module inside. When the NFC unit is turned on, the total current of
the chip is only 5mA@3.3V.
The underlying interaction is done independently by the NFC unit and does not occupy the CPU.
In addition, the 52840 itself is a high-performance low-power Bluetooth chip, and the encryption and calculation process
is only 7mA@3.3V. It can greatly reduce the battery volume and prolong the working time. That is to say, the 35mAh 10mm*
40mm button lithium battery can guarantee to be charged once every half a year under the working condition of swiping
the card 8 times a day for 3 seconds each time. Full potential for everyday use.
# 2. Not just UID, but a real and complete MIFARE encrypted data simulation
We can easily and completely simulate all data and password verification of all sectors, and can customize SAK, ATQA,
ATS, etc. Similar to an open CPU card development platform, 14A interaction of various architectures can be easily
realized.
# 3. Super compatibility with low-power locks using batteries
The structure of the old Chameleon AVR is slow to start during simulation. Faced with a battery-powered low-power lock
and an integrated lock on the door, it will be frequently interrupted, and the verification interaction cannot be
completed completely, resulting in no response when swiping the card.
In order to reduce power consumption, the battery lock will send out a field signal as short as possible when searching
for a card, which is no problem for the original card, but it is fatal for the MCU simulated card. Cards or mobile smart
bracelets simulated by the MCU cannot wake up and respond in such a short time, so many battery locks cannot open the
door, which greatly reduces the user experience.
This project specially optimizes the start-up and interaction logic and antenna for low-power reading heads. After
testing a variety of common low-power reading heads, they can open the door perfectly by swiping the card.
# 4. Ultra-fast response speed and low interaction delay(MifareClassic)
[fdt_standard_s50]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Standard_m1_s50.png
[fdt_redmi_k30]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Xiaomi_k30u_smartkey.png
[fdt_pm3_rdv401]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Proxmark3_Rdv4_RRG_(Firmware%20build%20at%2020201026).png
[fdt_chameleon_ultra]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/ChameleonUltra.png
[fdt_chameleon_tiny]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/ChameleonTiny.png
[fdt_flipper_zero]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/FlipperZero%20Simulation.png
| Simulation | FDT | "**_FDT_**" Rating |
|----------------------|:---------------------------:|:--------------------------------------------------------------------------------:|
| Standard MIFARE Card | ![alt][fdt_standard_s50] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| ChameleonUltra | ![alt][fdt_chameleon_ultra] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| Proxmark3 Rdv4.01 | ![alt][fdt_pm3_rdv401] | &#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| RedMi K30 | ![alt][fdt_redmi_k30] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| ChameleonTiny | ![alt][fdt_chameleon_tiny] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| FlipperZero | ![alt][fdt_flipper_zero] | &#x2B50;&#x2B50; |
# 5. 256kB super large RAM cooperates with RC522 to replace Proxmark3 magically to complete the decoding
[attack_mifare_darkside]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Darkside.png
[attack_mifare_nested]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Nested.png
[attack_mifare_mfkey32]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/MFKEY32V2.png
| Attack Type | CLI |
|--------------|:------------------------------:|
| MFKEY32 V2 | ![alt][attack_mifare_mfkey32] |
| Darkside | ![alt][attack_mifare_darkside] |
| Nested | ![alt][attack_mifare_nested] |
| StaticNested | Coming Soon |
| HardNested | Coming Soon |
| Relay attack | Coming Soon |
# Hardware frame diagram:
![alt text](https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Hardware%20%20Frame%20Diagram.png)
# Hardware Pictures
![alt text](https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Hardware%20Photos.png)
+215
View File
@@ -0,0 +1,215 @@
[nrf52_nfc_module_doc]: https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fnfc.html
[nxp_rc522_datasheet]: https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf
# ChameleonUltra
Why not keep using ATxmega128?
First of all, it is difficult to buy chips because the lead time for the main chip is too long, and because the price
has skyrocketed. Secondly, because the interaction speed of the ATxmega simulation is slow, the decryption performance
of the READER mode cannot meet the needs, and the low-frequency function cannot be added, so we have been trying to
upgrade it, such as using the latest ARM to replace the AVR framework, and the performance will definitely be greatly
improved.
# Why NRF52840?
NRF52840 has a built-in NFC Tag-A module, but no one seems to care about it. After playing with HydraNFC's TRF7970A and
FlipperZero's ST25R3916, ~~the developers found that they can only simulate MIFARE UID~~. I accidentally tested the NFC of
52840, and found that it is not only surprisingly easy to simulate a complete MIFARE card, but also has very good
simulation performance, friendly data flow interaction, and very fast response, unlike the former which is limited by
the SPI bus clock rate. We also found that it has ultra-low power consumption, ultra-small size, 256kb/1M large RAM and
FLASH, also has BLE5.0 and USB2.0 FS, super CotexM4F, most importantly, he is very cheap! This is undoubtedly a treasure
discovery for us!
Below we will explain in detail how we exploited the performance of the NRF52840, and what seemingly impossible
functions have been realized with it!
**Update**:
* FlipperZero can simulate mifare sector now, but FDT so high.
# Supported functions
## High Frequency Attack
| Attack Type | Tag Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------|:-------------:|------------------------------:|---------------------------|:--------------------------------------:|------------------------:|
| Sniffing | No | No | No | No | |
| MFKEY32 V2 | MifareClassic | Support | Support | Support | MifareClassic Detection |
| Darkside | MifareClassic | Support | Support | Support | Encrypted 4 bit NAck |
| Nested | MifareClassic | Support | Support | Support | PRNG(Distance guess) |
| StaticNested | MifareClassic | Support | Support | Not yet implemented | PRNG(2NT Fast Decrypt) |
| HardNested | MifareClassic | Support | Support | Not yet implemented | No |
| Relay attack | ISO14443A | Support | Support | Not yet implemented | No |
## High Frequency Simulation
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|-------------------------------|:--------------------:|------------------------------:|---------------------------|:--------------------------------------:|-----------------------------------------:|
| Non <13.56MHz or ISO14443A> | No | No | No | No | [NRF52 NFC Module][nrf52_nfc_module_doc] |
| NTAG 21x (210-218) | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight Ev1 | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight C | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| MifareClassic1K/2K/4K (4B/7B) | ISO14443A/106 kbit/s | Support | Support | Support | |
| Mifare DESFire | ISO14443A High Rate | Only supported Low rate | Only supported Low rate | Not yet implemented | |
| Mifare DESFire EV1 | ISO14443A High rate | Only supported Low rate | Only supported Low rate | Not yet implemented | Backward compatible |
| Mifare DESFire EV2 | ISO14443A High rate | Only supported Low rate | Only supported Low rate | Not yet implemented | |
| Mifare PLUS | ISO14443A High rate | Only supported Low rate | Only supported Low rate | Not yet implemented | |
## High Frequency Reader
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|-------------------------------|:--------------------:|---------------------------------------------:|----------------------------------------------|:--------------------------------------:|-------------------------------------------:|
| Non <13.56MHz or ISO14443A> | No | No | No | No | [NXP RC522 Datasheet][nxp_rc522_datasheet] |
| NTAG 21x (210-218) | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight Ev1 | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| Mifare Ultralight C | ISO14443A/106 kbit/s | Support | Support | Not yet implemented | |
| MifareClassic1K/2K/4K (4B/7B) | ISO14443A/106 kbit/s | Support | Support | Support | |
| Mifare DESFire | ISO14443A High Rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | |
| Mifare DESFire EV1 | ISO14443A High rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | Backward compatible |
| Mifare DESFire EV2 | ISO14443A High rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | |
| Mifare PLUS | ISO14443A High rate | Supports low rates, or possibly higher rates | Supports low rates, or possibly higher rates | Not yet implemented | |
## Low Frequency Attack
| Vulnerability Type | Tag Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------------|:---------:|------------------------------:|---------------------------|:--------------------------------------:|-----:|
| Sniffing | 125KHz | Support | Support | Not yet implemented | |
| Brute Force | EM410x ID | Support | Support | Not yet implemented | |
## Low Frequency Simulation
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------------------|:-------------:|------------------------------:|---------------------------|:--------------------------------------:|----------------------------------------------:|
| Non <125KHz/ASK/PSK/FSK> | No | No | No | No | Only 125 khz RF, Modulation ASK, FSK and PSK. |
| EM410x | ASK | Support | Support | Support | EM4100 is support(AD 64bit) |
| T5577 | ASK | Support | Support | Not yet implemented | |
| HID Prox | FSK | Support | Support | Not yet implemented | |
| Indala | PSK | Support | Support | Not yet implemented | |
| FDX-B | ASK | Support | Support | Not yet implemented | |
| Paradox | FSK | Support | Support | Not yet implemented | |
| Keri | PSK | Support | Support | Not yet implemented | |
| AWD | FSK | Support | Support | Not yet implemented | |
| ioProx | FSK | Support | Support | Not yet implemented | |
| securakey | ASK | Support | Support | Not yet implemented | |
| gallagher | ASK | Support | Support | Not yet implemented | |
| PAC/Stanley | ASK | Support | Support | Not yet implemented | |
| Presco | ASK | Support | Support | Not yet implemented | |
| Visa2000 | ASK | Support | Support | Not yet implemented | |
| Viking | ASK | Support | Support | Not yet implemented | |
| Noralsy | ASK | Support | Support | Not yet implemented | |
| NexWatch | PSK | Support | Support | Not yet implemented | |
| Jablotron | ASK | Support | Support | Not yet implemented | |
## Low Frequency Reader
| Card Type | Encoding Type | Whether the hardware supports | Does the software support | Whether the application layer supports | Note |
|--------------------------|:-------------:|------------------------------:|---------------------------|:--------------------------------------:|----------------------------------------------:|
| Non <125KHz/ASK/PSK/FSK> | No | No | No | No | Only 125 khz RF, Modulation ASK, FSK and PSK. |
| EM410x | ASK | Support | Support | Support | |
| T5577 | ASK | Support | Support | Support(Write) | |
| HID Prox | FSK | Support | Support | Not yet implemented | |
| Indala | PSK | Support | Support | Not yet implemented | |
| FDX-B | ASK | Support | Support | Not yet implemented | |
| Paradox | FSK | Support | Support | Not yet implemented | |
| Keri | PSK | Support | Support | Not yet implemented | |
| AWD | FSK | Support | Support | Not yet implemented | |
| ioProx | FSK | Support | Support | Not yet implemented | |
| securakey | ASK | Support | Support | Not yet implemented | |
| gallagher | ASK | Support | Support | Not yet implemented | |
| PAC/Stanley | ASK | Support | Support | Not yet implemented | |
| Presco | ASK | Support | Support | Not yet implemented | |
| Visa2000 | ASK | Support | Support | Not yet implemented | |
| Viking | ASK | Support | Support | Not yet implemented | |
| Noralsy | ASK | Support | Support | Not yet implemented | |
| NexWatch | PSK | Support | Support | Not yet implemented | |
| Jablotron | ASK | Support | Support | Not yet implemented | |
## Low Frequency Modulation
[modulation_psk]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/PSK.png
[modulation_fsk]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/FSK.png
[modulation_ask]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/ASK.png
| Modulation Type | wav |
|-----------------|----------------------------:|
| PSK | ![alt text][modulation_psk] |
| FSK | ![alt text][modulation_fsk] |
| ASK | ![alt text][modulation_ask] |
# 1. Ultra-low power consumption
It integrates a high-performance and low-power NFC module inside. When the NFC unit is turned on, the total current of
the chip is only 5mA@3.3V.
The underlying interaction is done independently by the NFC unit and does not occupy the CPU.
In addition, the 52840 itself is a high-performance low-power Bluetooth chip, and the encryption and calculation process
is only 7mA@3.3V. It can greatly reduce the battery volume and prolong the working time. That is to say, the 35mAh 10mm*
40mm button lithium battery can guarantee to be charged once every half a year under the working condition of swiping
the card 8 times a day for 3 seconds each time. Full potential for everyday use.
# 2. Not just UID, but a real and complete MIFARE encrypted data simulation
We can easily and completely simulate all data and password verification of all sectors, and can customize SAK, ATQA,
ATS, etc. Similar to an open CPU card development platform, 14A interaction of various architectures can be easily
realized.
# 3. Super compatibility with low-power locks using batteries
The structure of the old Chameleon AVR is slow to start during simulation. Faced with a battery-powered low-power lock
and an integrated lock on the door, it will be frequently interrupted, and the verification interaction cannot be
completed completely, resulting in no response when swiping the card.
In order to reduce power consumption, the battery lock will send out a field signal as short as possible when searching
for a card, which is no problem for the original card, but it is fatal for the MCU simulated card. Cards or mobile smart
bracelets simulated by the MCU cannot wake up and respond in such a short time, so many battery locks cannot open the
door, which greatly reduces the user experience.
This project specially optimizes the start-up and interaction logic and antenna for low-power reading heads. After
testing a variety of common low-power reading heads, they can open the door perfectly by swiping the card.
# 4. Ultra-fast response speed and low interaction delay(MifareClassic)
[fdt_standard_s50]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Standard_m1_s50.png
[fdt_redmi_k30]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Xiaomi_k30u_smartkey.png
[fdt_pm3_rdv401]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Proxmark3_Rdv4_RRG_(Firmware%20build%20at%2020201026).png
[fdt_chameleon_ultra]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/ChameleonUltra.png
[fdt_chameleon_tiny]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/ChameleonTiny.png
[fdt_flipper_zero]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/FlipperZero%20Simulation.png
| Simulation | FDT | "**_FDT_**" Rating |
|----------------------|:---------------------------:|:--------------------------------------------------------------------------------:|
| Standard MIFARE Card | ![alt][fdt_standard_s50] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| ChameleonUltra | ![alt][fdt_chameleon_ultra] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| Proxmark3 Rdv4.01 | ![alt][fdt_pm3_rdv401] | &#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| RedMi K30 | ![alt][fdt_redmi_k30] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| ChameleonTiny | ![alt][fdt_chameleon_tiny] | &#x2B50;&#x2B50;&#x2B50;&#x2B50;&#x2B50; |
| FlipperZero | ![alt][fdt_flipper_zero] | &#x2B50;&#x2B50; |
# 5. 256kB super large RAM cooperates with RC522 to replace Proxmark3 magically to complete the decoding
[attack_mifare_darkside]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Darkside.png
[attack_mifare_nested]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Nested.png
[attack_mifare_mfkey32]: https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/MFKEY32V2.png
| Attack Type | CLI |
|--------------|:------------------------------:|
| MFKEY32 V2 | ![alt][attack_mifare_mfkey32] |
| Darkside | ![alt][attack_mifare_darkside] |
| Nested | ![alt][attack_mifare_nested] |
| StaticNested | Coming Soon |
| HardNested | Coming Soon |
| Relay attack | Coming Soon |
# Hardware frame diagram:
![alt text](https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/resource/picture/Hardware%20%20Frame%20Diagram.png)
+2 -1
View File
@@ -6,7 +6,8 @@ ARG NRF_CLT_URL=https://nsscprodmedia.blob.core.windows.net/prod/software-and-ot
RUN set -xe; \
DEBIAN_FRONTEND=noninteractive; \
apt update -q; \
apt install -qy --no-install-recommends ca-certificates curl xz-utils make; \
apt install -qy --no-install-recommends ca-certificates curl xz-utils make git; \
git config --global --add safe.directory /workdir; \
curl -sLo /usr/bin/nrfutil https://developer.nordicsemi.com/.pc-tools/nrfutil/x64-linux/nrfutil; \
curl -sLo /tmp/nrf-clt.deb $NRF_CLT_URL; \
apt install -qfy /tmp/nrf-clt.deb; \
+7
View File
@@ -22,4 +22,11 @@ LD_DIR := $(SRC_COMMON)
CHAMELEON_ULTRA := ultra
CHAMELEON_LITE := lite
# What device is it?
CURRENT_DEVICE_TYPE ?= ${CHAMELEON_ULTRA}
# Versioning information
GIT_VERSION := "$(shell git describe --abbrev=7 --dirty --always --tags)"
# Enable NRF_LOG on SWO pin as UART TX
NRF_LOG_UART_ON_SWO_ENABLED := 0
+29 -5
View File
@@ -7,14 +7,17 @@ $(OUTPUT_DIRECTORY)/application.out: \
# Source files common to all targets
SRC_FILES += \
$(SRC_COMMON)/hw_connect.c \
$(SRC_COMMON)/libc_nano_stubs.c \
$(PROJ_DIR)/app_main.c \
$(PROJ_DIR)/app_cmd.c \
$(PROJ_DIR)/ble_main.c \
$(PROJ_DIR)/rfid_main.c \
$(PROJ_DIR)/settings.c \
$(PROJ_DIR)/usb_main.c \
$(PROJ_DIR)/rgb_marquee.c \
$(PROJ_DIR)/bsp/bsp_delay.c \
$(PROJ_DIR)/bsp/bsp_time.c \
$(PROJ_DIR)/bsp/bsp_wdt.c \
$(PROJ_DIR)/rfid/crc_utils.c \
$(PROJ_DIR)/rfid/hex_utils.c \
$(PROJ_DIR)/rfid/mf1_crapto1.c \
@@ -28,6 +31,7 @@ SRC_FILES += \
$(PROJ_DIR)/rfid/nfctag/hf/nfc_ntag.c \
$(PROJ_DIR)/rfid/nfctag/lf/lf_tag_em.c \
$(PROJ_DIR)/utils/dataframe.c \
$(PROJ_DIR)/utils/delayed_reset.c \
$(PROJ_DIR)/utils/fds_util.c \
$(PROJ_DIR)/utils/syssleep.c \
$(PROJ_DIR)/utils/timeslot.c \
@@ -91,6 +95,7 @@ SRC_FILES += \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_spi.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_rng.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_ppi.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_wdt.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \
@@ -286,6 +291,23 @@ else
$(error Chameleon <Application>: No device type define.)
endif
ifeq (${NRF_LOG_UART_ON_SWO_ENABLED}, 1)
SRC_FILES += \
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_uart.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_uart.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_uarte.c
CFLAGS += -DNRFX_UARTE_ENABLED=1 -DNRFX_UARTE0_ENABLED=1
CFLAGS += -DNRF_LOG_BACKEND_UART_ENABLED=1
#define NRF_GPIO_PIN_MAP(port, pin) (((port) << 5) | ((pin) & 0x1F))
#define NRF_LOG_BACKEND_UART_TX_PIN NRF_GPIO_PIN_MAP(1, 0)
CFLAGS += -DNRF_LOG_BACKEND_UART_TX_PIN=32
# 30801920 = 115200 baud
CFLAGS += -DNRF_LOG_BACKEND_UART_BAUDRATE=30801920
CFLAGS += -DNRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE=64
$(info Chameleon <Application>: enable NRF_LOG on UART via SWO pin.)
endif
# Optimization flags
OPT = -O3 -g3
@@ -311,6 +333,9 @@ CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -fno-builtin -fshort-enums
# Versioning flags
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
# C++ flags common to all targets
CXXFLAGS += $(OPT)
# Assembler flags common to all targets
@@ -366,14 +391,13 @@ TEMPLATE_PATH := $(SDK_ROOT)/components/toolchain/gcc
include ../Makefile.defs
include $(TEMPLATE_PATH)/Makefile.common
# tolerate warnings in newer gcc versions
# need to be called after $(TEMPLATE_PATH)/Makefile.common
CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//')
CC_VERSION := $(or $(strip $(CC_VERSION)),0)
CFLAGS += -Wno-error=array-bounds
ifeq ($(shell expr $(CC_VERSION) \>= 12), 1)
CFLAGS += -Wno-error=sizeof-array-div
endif
# usage example:
#ifeq ($(shell expr $(CC_VERSION) \>= 12), 1)
# CFLAGS += -Wno-error=sizeof-array-div
#endif
$(foreach target, $(TARGETS), $(call define_target, $(target)))
+68 -4
View File
@@ -12,6 +12,8 @@
#include "app_status.h"
#include "tag_persistence.h"
#include "nrf_pwr_mgmt.h"
#include "settings.h"
#include "delayed_reset.h"
#define NRF_LOG_MODULE_NAME app_cmd
@@ -27,6 +29,12 @@ data_frame_tx_t* cmd_processor_get_version(uint16_t cmd, uint16_t status, uint16
return data_frame_make(cmd, status, 2, (uint8_t*)&version);
}
data_frame_tx_t* cmd_processor_get_git_version(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
return data_frame_make(cmd, status, strlen(GIT_VERSION), (uint8_t*)GIT_VERSION);
}
data_frame_tx_t* cmd_processor_change_device_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
#if defined(PROJECT_CHAMELEON_ULTRA)
if (length == 1) {
@@ -80,6 +88,32 @@ data_frame_tx_t* cmd_processor_get_device_address(uint16_t cmd, uint16_t status,
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 6, (uint8_t*)(&device_address[0]));
}
data_frame_tx_t* cmd_processor_save_settings(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
status = settings_save_config();
return data_frame_make(cmd, status, 0, NULL);
}
data_frame_tx_t* cmd_processor_reset_settings(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
settings_init_config();
status = settings_save_config();
return data_frame_make(cmd, status, 0, NULL);
}
data_frame_tx_t* cmd_processor_set_animation_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
if (length == 1) {
settings_set_animation_config(data[0]);
}
else {
status = STATUS_PAR_ERR;
}
return data_frame_make(cmd, status, 0, NULL);
}
data_frame_tx_t* cmd_processor_get_animation_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
uint8_t animation_mode = settings_get_animation_config();
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 1, (uint8_t *)(&animation_mode));
}
#if defined(PROJECT_CHAMELEON_ULTRA)
data_frame_tx_t* cmd_processor_14a_scan(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
@@ -307,6 +341,30 @@ data_frame_tx_t* cmd_processor_slot_data_config_save(uint16_t cmd, uint16_t stat
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 0, NULL);
}
data_frame_tx_t* cmd_processor_get_activated_slot(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
uint8_t slot = tag_emulation_get_slot();
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 1, &slot);
}
data_frame_tx_t* cmd_processor_get_slot_info(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
uint8_t slot_info[16] = {};
tag_specific_type_t tag_type[2];
for (uint8_t slot = 0; slot < 8; slot++) {
tag_emulation_get_specific_type_by_slot(slot, tag_type);
slot_info[slot * 2] = tag_type[0];
slot_info[slot * 2 + 1] = tag_type[1];
}
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 16, slot_info);
}
data_frame_tx_t* cmd_processor_wipe_fds(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
bool success = fds_wipe();
status = success ? STATUS_DEVICE_SUCCESS : STATUS_FLASH_WRITE_FAIL;
delayed_reset(50);
return data_frame_make(cmd, status, 0, NULL);
}
data_frame_tx_t* cmd_processor_set_em410x_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
if (length == LF_EM410X_TAG_ID_SIZE) {
tag_data_buffer_t* buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
@@ -380,13 +438,13 @@ data_frame_tx_t* cmd_processor_get_mf1_detection_log(uint16_t cmd, uint16_t stat
data_frame_tx_t* cmd_processor_set_mf1_emulator_block(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
if (length > 0 && (((length - 1) % NFC_TAG_MF1_DATA_SIZE) == 0)) {
uint8_t block_index = data[0];
uint8_t block_count = (length - 1) % NFC_TAG_MF1_DATA_SIZE;
uint8_t block_count = (length - 1) / NFC_TAG_MF1_DATA_SIZE;
if (block_index + block_count > NFC_TAG_MF1_BLOCK_MAX) {
status = STATUS_PAR_ERR;
} else {
tag_data_buffer_t* buffer = get_buffer_by_tag_type(TAG_TYPE_MIFARE_4096);
nfc_tag_mf1_information_t *info = (nfc_tag_mf1_information_t *)buffer->buffer;
for (int i = 1, j = block_index; i < length - 1; i += NFC_TAG_MF1_DATA_SIZE, j++) {
for (int i = 1, j = block_index; i < length; i += NFC_TAG_MF1_DATA_SIZE, j++) {
uint8_t *p_block = &data[i];
memcpy(info->memory[j], p_block, NFC_TAG_MF1_DATA_SIZE);
}
@@ -423,7 +481,6 @@ data_frame_tx_t* cmd_processor_set_mf1_anti_collision_res(uint16_t cmd, uint16_t
}
data_frame_tx_t* cmd_processor_set_slot_tag_nick_name(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
// one chinese have 2byte(gbk).
if (length > 34 || length < 3) {
status = STATUS_PAR_ERR;
} else {
@@ -448,7 +505,6 @@ data_frame_tx_t* cmd_processor_set_slot_tag_nick_name(uint16_t cmd, uint16_t sta
}
data_frame_tx_t* cmd_processor_get_slot_tag_nick_name(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
// one chinese have 2byte(gbk).
if (length != 2) {
status = STATUS_PAR_ERR;
} else {
@@ -524,6 +580,11 @@ static cmd_data_map_t m_data_cmd_map[] = {
{ DATA_CMD_ENTER_BOOTLOADER, NULL, cmd_processor_enter_bootloader, NULL },
{ DATA_CMD_GET_DEVICE_CHIP_ID, NULL, cmd_processor_get_device_chip_id, NULL },
{ DATA_CMD_GET_DEVICE_ADDRESS, NULL, cmd_processor_get_device_address, NULL },
{ DATA_CMD_SAVE_SETTINGS, NULL, cmd_processor_save_settings, NULL },
{ DATA_CMD_RESET_SETTINGS, NULL, cmd_processor_reset_settings, NULL },
{ DATA_CMD_SET_ANIMATION_MODE, NULL, cmd_processor_set_animation_mode, NULL },
{ DATA_CMD_GET_ANIMATION_MODE, NULL, cmd_processor_get_animation_mode, NULL },
{ DATA_CMD_GET_GIT_VERSION, NULL, cmd_processor_get_git_version, NULL },
#if defined(PROJECT_CHAMELEON_ULTRA)
@@ -550,6 +611,9 @@ static cmd_data_map_t m_data_cmd_map[] = {
{ DATA_CMD_SET_SLOT_DATA_DEFAULT, NULL, cmd_processor_set_slot_data_default, NULL },
{ DATA_CMD_SET_SLOT_ENABLE, NULL, cmd_processor_set_slot_enable, NULL },
{ DATA_CMD_SLOT_DATA_CONFIG_SAVE, NULL, cmd_processor_slot_data_config_save, NULL },
{ DATA_CMD_GET_ACTIVE_SLOT, NULL, cmd_processor_get_activated_slot, NULL },
{ DATA_CMD_GET_SLOT_INFO, NULL, cmd_processor_get_slot_info, NULL },
{ DATA_CMD_WIPE_FDS, NULL, cmd_processor_wipe_fds, NULL },
{ DATA_CMD_SET_EM410X_EMU_ID, NULL, cmd_processor_set_em410x_emu_id, NULL },
+41 -19
View File
@@ -27,6 +27,7 @@ NRF_LOG_MODULE_REGISTER();
#include "ble_main.h"
#include "bsp_delay.h"
#include "bsp_time.h"
#include "bsp_wdt.h"
#include "dataframe.h"
#include "fds_util.h"
#include "hex_utils.h"
@@ -36,6 +37,7 @@ NRF_LOG_MODULE_REGISTER();
#include "usb_main.h"
#include "rgb_marquee.h"
#include "settings.h"
// Defining soft timers
APP_TIMER_DEF(m_button_check_timer); // Timer for button debounce
@@ -219,22 +221,25 @@ static void system_off_enter(void) {
for (uint8_t i = 0; i < RGB_LIST_NUM; i++) {
nrf_gpio_pin_clear(p_led_array[i]);
}
uint8_t slot = tag_emulation_get_slot();
// Power off animation
uint8_t dir = slot > 3 ? 1 : 0;
uint8_t color = get_color_by_slot(slot);
if (m_reset_source & (NRF_POWER_RESETREAS_NFC_MASK | NRF_POWER_RESETREAS_LPCOMP_MASK)) {
if (m_reset_source & NRF_POWER_RESETREAS_NFC_MASK) {
color = 1;
} else {
color = 2;
uint8_t animation_config = settings_get_animation_config();
if (animation_config == SettingsAnimationModeFull) {
uint8_t slot = tag_emulation_get_slot();
// Power off animation
uint8_t dir = slot > 3 ? 1 : 0;
uint8_t color = get_color_by_slot(slot);
if (m_reset_source & (NRF_POWER_RESETREAS_NFC_MASK | NRF_POWER_RESETREAS_LPCOMP_MASK)) {
if (m_reset_source & NRF_POWER_RESETREAS_NFC_MASK) {
color = 1;
} else {
color = 2;
}
}
ledblink5(color, slot, dir ? 7 : 0);
ledblink4(color, dir, 7, 99, 75);
ledblink4(color, !dir, 7, 75, 50);
ledblink4(color, dir, 7, 50, 25);
ledblink4(color, !dir, 7, 25, 0);
}
ledblink5(color, slot, dir ? 7 : 0);
ledblink4(color, dir, 7, 99, 75);
ledblink4(color, !dir, 7, 75, 50);
ledblink4(color, dir, 7, 50, 25);
ledblink4(color, !dir, 7, 25, 0);
rgb_marquee_stop();
}
@@ -346,9 +351,18 @@ static void check_wakeup_src(void) {
advertising_start(); // Turn on Bluetooth radio
// Button wake-up boot animation
ledblink2(color, !dir, 11);
ledblink2(color, dir, 11);
ledblink2(color, !dir, dir ? slot : 7 - slot);
uint8_t animation_config = settings_get_animation_config();
if (animation_config == SettingsAnimationModeFull)
{
ledblink2(color, !dir, 11);
ledblink2(color, dir, 11);
ledblink2(color, !dir, dir ? slot : 7 - slot);
} else if (animation_config == SettingsAnimationModeMinimal) {
ledblink2(color, !dir, dir ? slot : 7 - slot);
} else {
set_slot_light_color(color);
}
// The indicator of the current card slot lights up at the end of the animation
light_up_by_slot();
@@ -374,8 +388,11 @@ static void check_wakeup_src(void) {
// 当前是模拟卡事件唤醒系统,我们可以让场强灯先亮起来
TAG_FIELD_LED_ON();
// In the case of field wake-up, only one round of RGB is swept as the power-on animation
ledblink2(color, !dir, dir ? slot : 7 - slot);
uint8_t animation_config = settings_get_animation_config();
if (animation_config == SettingsAnimationModeFull) {
// In the case of field wake-up, only one round of RGB is swept as the power-on animation
ledblink2(color, !dir, dir ? slot : 7 - slot);
}
set_slot_light_color(color);
light_up_by_slot();
@@ -517,6 +534,8 @@ int main(void) {
tag_emulation_init(); // Analog card initialization
rgb_marquee_init(); // Light effect initialization
settings_load_config(); // Load settings from flash
// cmd callback register
on_data_frame_complete(on_data_frame_received);
@@ -526,6 +545,7 @@ int main(void) {
// usbd event listener
APP_ERROR_CHECK(app_usbd_power_events_enable());
bsp_wdt_init();
// Enter main loop.
NRF_LOG_INFO("Chameleon working");
while (1) {
@@ -539,6 +559,8 @@ int main(void) {
while (NRF_LOG_PROCESS());
// USB event process
while (app_usbd_event_queue_process());
// WDT refresh
bsp_wdt_feed();
// No task to process, system sleep enter.
// If system idle sometime, we can enter deep sleep state.
// Some task process done, we can enter cpu sleep state.
+30
View File
@@ -0,0 +1,30 @@
#include "nrf_drv_wdt.h"
#include "hw_connect.h"
#include "nrf_gpio.h"
static nrf_drv_wdt_channel_id m_channel_id;
static void wdt_event_handler(void)
{
//NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
uint32_t* p_led_array = hw_get_led_array();
for (uint8_t i = 0; i < RGB_LIST_NUM; i++) {
nrf_gpio_pin_clear(p_led_array[i]);
}
}
void bsp_wdt_init(void) {
ret_code_t err_code;
// err_code = nrf_drv_clock_init(); // already done by usb_cdc_init() -> app_usbd_init()
// APP_ERROR_CHECK(err_code);
nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG; // typo is in the SDK...
err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
APP_ERROR_CHECK(err_code);
nrf_drv_wdt_enable();
}
void bsp_wdt_feed(void) {
nrf_drv_wdt_channel_feed(m_channel_id);
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef __BSP_WDT_H__
#define __BSP_WDT_H__
#ifdef __cplusplus
extern "C" {
#endif
void bsp_wdt_init(void);
void bsp_wdt_feed(void);
#ifdef __cplusplus
}
#endif
#endif // __BSP_WDT_H__
+8
View File
@@ -20,6 +20,14 @@
#define DATA_CMD_ENTER_BOOTLOADER (1010)
#define DATA_CMD_GET_DEVICE_CHIP_ID (1011)
#define DATA_CMD_GET_DEVICE_ADDRESS (1012)
#define DATA_CMD_SAVE_SETTINGS (1013)
#define DATA_CMD_RESET_SETTINGS (1014)
#define DATA_CMD_SET_ANIMATION_MODE (1015)
#define DATA_CMD_GET_ANIMATION_MODE (1016)
#define DATA_CMD_GET_GIT_VERSION (1017)
#define DATA_CMD_GET_ACTIVE_SLOT (1018)
#define DATA_CMD_GET_SLOT_INFO (1019)
#define DATA_CMD_WIPE_FDS (1020)
//
// ******************************************************************
@@ -3,6 +3,7 @@
#include "lf_tag_em.h"
#include "nfc_mf1.h"
#include "nfc_ntag.h"
#include "fds_ids.h"
#include "fds_util.h"
#include "tag_emulation.h"
#include "tag_persistence.h"
@@ -383,7 +384,7 @@ void tag_emulation_sense_switch(tag_sense_type_t type, bool enable) {
*/
void tag_emulation_load_config(void) {
// 读取卡槽配置数据
bool ret = fds_read_sync(FDS_CONFIG_RECORD_FILE_ID, FDS_CONFIG_RECORD_FILE_KEY, sizeof(slotConfig), (uint8_t *)&slotConfig);
bool ret = fds_read_sync(FDS_EMULATION_CONFIG_FILE_ID, FDS_EMULATION_CONFIG_RECORD_KEY, sizeof(slotConfig), (uint8_t *)&slotConfig);
if (ret) {
// 读取完成后,我们先保存一份当前配置的BCC,后面保存的时候可以作为变动对比的参考
calc_14a_crc_lut((uint8_t *)&slotConfig, sizeof(slotConfig), (uint8_t *)&m_slot_config_crc);
@@ -402,7 +403,7 @@ void tag_emulation_save_config(void) {
calc_14a_crc_lut((uint8_t *)&slotConfig, sizeof(slotConfig), (uint8_t *)&new_calc_crc);
if (new_calc_crc != m_slot_config_crc) { // 在保存之前,先确保卡槽配置有变动了
NRF_LOG_INFO("Save tag slot config start.");
bool ret = fds_write_sync(FDS_CONFIG_RECORD_FILE_ID, FDS_CONFIG_RECORD_FILE_KEY, sizeof(slotConfig) / 4, (uint8_t *)&slotConfig);
bool ret = fds_write_sync(FDS_EMULATION_CONFIG_FILE_ID, FDS_EMULATION_CONFIG_RECORD_KEY, sizeof(slotConfig) / 4, (uint8_t *)&slotConfig);
if (ret) {
NRF_LOG_INFO("Save tag slot config success.");
} else {
@@ -5,12 +5,11 @@
#include <stdint.h>
#include <stdbool.h>
#include "utils.h"
#include "tag_base_type.h"
// 最多八张卡槽
#define TAG_MAX_SLOT_NUM 8
// u32 size align.
#define ALIGN_U32 __attribute__((aligned(4)))
extern bool g_is_tag_emulating;
@@ -1,5 +1,5 @@
#include "tag_persistence.h"
#include "fds_ids.h"
#define NRF_LOG_MODULE_NAME tag_persistence
#include "nrf_log.h"
@@ -9,35 +9,24 @@ NRF_LOG_MODULE_REGISTER();
void get_fds_map_by_slot_auto_inc_id(uint16_t key, uint16_t id, uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) {
map->key = key + slot;
uint8_t base_id = 0;
switch(sense_type) {
case TAG_SENSE_HF:
base_id = 0;
break;
case TAG_SENSE_LF:
base_id = 1;
break;
case TAG_SENSE_NO:
// never to here...(if dev wrong, must fix)
APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM);
static void get_fds_map_by_slot_auto_inc_id(uint16_t id, uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) {
if ((sense_type == TAG_SENSE_NO) || (slot > 7)) {
APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM);
}
map->id = id + base_id;
map->id = id + slot;
map->key = sense_type;
}
/**
* FDS中对应的数据的KEY和ID
* Obtain the KEY and ID of the corresponding data in FDS according to the card slot and the field type specified in the card slot
*/
void get_fds_map_by_slot_sense_type_for_dump(uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) {
// 根据 @see FDS_SLOT_TAG_DUMP_FILE_KEY 的约定,每个slot以其为起点,每个slot都有其单独的key的record,并且每个slot中独特的场类型也有一个数据的id
get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_DUMP_FILE_KEY, FDS_SLOT_TAG_DUMP_FILE_ID, slot, sense_type, map);
get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_DUMP_FILE_ID_BASE, slot, sense_type, map);
}
/**
* FDS中对应的数据的KEY和ID
* Obtain the KEY and ID of the corresponding data in FDS according to the card slot and the field type specified in the card slot
*/
void get_fds_map_by_slot_sense_type_for_nick(uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) {
get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_NICK_NAME_KEY, FDS_SLOT_TAG_NICK_NAME_ID, slot, sense_type, map);
get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_NICK_NAME_FILE_ID_BASE, slot, sense_type, map);
}
@@ -5,27 +5,6 @@
#include "tag_base_type.h"
/*
*
*/
#define FDS_CONFIG_RECORD_FILE_KEY 0x1066
#define FDS_CONFIG_RECORD_FILE_ID 0x1066
/*
* key是跟卡槽走的id+n就等于数据索引
* slot的file_key都不一样
* slot有两种类型的卡片ID
*/
#define FDS_SLOT_TAG_DUMP_FILE_KEY 0x1067
#define FDS_SLOT_TAG_DUMP_FILE_ID 0x1067
/*
* key是跟卡槽走的id+n就等于数据索引
*/
#define FDS_SLOT_TAG_NICK_NAME_KEY 0x1068
#define FDS_SLOT_TAG_NICK_NAME_ID 0x1068
typedef struct {
uint16_t key;
uint16_t id;
+11 -9
View File
@@ -4630,7 +4630,7 @@
// <e> NRFX_WDT_ENABLED - nrfx_wdt - WDT peripheral driver
//==========================================================
#ifndef NRFX_WDT_ENABLED
#define NRFX_WDT_ENABLED 0
#define NRFX_WDT_ENABLED 1
#endif
// <o> NRFX_WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode
@@ -4647,7 +4647,7 @@
#ifndef NRFX_WDT_CONFIG_RELOAD_VALUE
#define NRFX_WDT_CONFIG_RELOAD_VALUE 2000
#define NRFX_WDT_CONFIG_RELOAD_VALUE 5000
#endif
// <o> NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver
@@ -4677,7 +4677,7 @@
// <e> NRFX_WDT_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef NRFX_WDT_CONFIG_LOG_ENABLED
#define NRFX_WDT_CONFIG_LOG_ENABLED 0
#define NRFX_WDT_CONFIG_LOG_ENABLED 1
#endif
// <o> NRFX_WDT_CONFIG_LOG_LEVEL - Default Severity level
@@ -5868,9 +5868,10 @@
// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
//==========================================================
#ifndef UART_ENABLED
#define UART_ENABLED 0
#endif
//Don't define it at all else it conflicts with NRFX
//#ifndef UART_ENABLED
//#define UART_ENABLED 0
//#endif
// <o> UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control
// <0=> Disabled
@@ -6018,9 +6019,10 @@
// <e> WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver - legacy layer
//==========================================================
#ifndef WDT_ENABLED
#define WDT_ENABLED 0
#endif
//Don't define it at all else it conflicts with NRFX
//#ifndef WDT_ENABLED
//#define WDT_ENABLED 0
//#endif
// <o> WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode
// <1=> Run in SLEEP, Pause in HALT
+117
View File
@@ -0,0 +1,117 @@
#include <stdbool.h>
#include "crc_utils.h"
#include "app_status.h"
#include "settings.h"
#include "fds_ids.h"
#include "fds_util.h"
#define NRF_LOG_MODULE_NAME settings
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
NRF_LOG_MODULE_REGISTER();
static settings_data_t config;
static uint16_t m_config_crc;
static void update_config_crc(void)
{
calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&m_config_crc);
}
static bool config_did_change(void)
{
uint16_t new_calc_crc;
calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&new_calc_crc);
return new_calc_crc != m_config_crc;
}
void settings_init_config(void)
{
config.version = SETTINGS_CURRENT_VERSION;
config.animation_config = SettingsAnimationModeFull;
}
void settings_migrate(void)
{
switch (config.version) {
case 0:
NRF_LOG_ERROR("Unexpected configuration version detected!");
settings_init_config();
break;
/*
* When needed migrations can be implemented like this:
*
* case 1:
* config->new_field = some_default_value;
* case 2:
* config->another_new_field = some_default_value;
* case 3:
* config->another_new_field = some_default_value;
* break;
*
* Note that the `break` statement should only be used on the last migration step, all the previous steps must fall
* through to the next case.
*/
default:
NRF_LOG_ERROR("Unsupported configuration migration attempted! (%d -> %d)", config.version, SETTINGS_CURRENT_VERSION);
break;
}
}
void settings_load_config(void)
{
bool ret = fds_read_sync(FDS_SETTINGS_FILE_ID, FDS_SETTINGS_RECORD_KEY, sizeof(config), (uint8_t *)&config);
if (ret) {
NRF_LOG_INFO("Load config done.");
// After the reading is complete, we first save a copy of the current CRC, which can be used as a reference for comparison of changes when saving later
update_config_crc();
} else {
NRF_LOG_WARNING("Config does not exist, loading default values...");
settings_init_config();
}
if (config.version > SETTINGS_CURRENT_VERSION) {
NRF_LOG_WARNING("Config version %d is greater than current firmware supports (%d). Default config will be loaded.", config.version, SETTINGS_CURRENT_VERSION);
settings_init_config();
}
if (config.version < SETTINGS_CURRENT_VERSION) {
NRF_LOG_INFO("Config version (%d) is not latest, performing migration to %d", config.version, SETTINGS_CURRENT_VERSION);
settings_migrate();
}
if (config_did_change()) {
settings_save_config();
}
}
uint8_t settings_save_config(void)
{
// We are saving the configuration, we need to calculate the crc code of the current configuration to judge whether the following data is updated
if (config_did_change()) { // Before saving, make sure that the configuration has changed
NRF_LOG_INFO("Save config start.");
bool ret = fds_write_sync(FDS_SETTINGS_FILE_ID, FDS_SETTINGS_RECORD_KEY, sizeof(config) / 4, (uint8_t *)&config);
if (ret) {
NRF_LOG_INFO("Save config success.");
update_config_crc();
}
else
{
NRF_LOG_ERROR("Save config error.");
return STATUS_FLASH_WRITE_FAIL;
}
} else {
NRF_LOG_INFO("Config did not change.");
}
return STATUS_DEVICE_SUCCESS;
}
uint8_t settings_get_animation_config()
{
return config.animation_config;
}
void settings_set_animation_config(uint8_t value)
{
config.animation_config = value;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef SETTINGS_H
#define SETTINGS_H
#include <stdint.h>
#include "utils.h"
#define SETTINGS_CURRENT_VERSION 1
typedef enum {
SettingsAnimationModeFull = 0,
SettingsAnimationModeMinimal = 1,
SettingsAnimationModeNone = 2,
} settings_animation_mode_t;
typedef struct ALIGN_U32 {
uint16_t version;
uint8_t animation_config : 2;
uint16_t reserved0 : 14;
uint32_t reserved1;
uint32_t reserved2;
} settings_data_t;
void settings_init_config(void);
void settings_migrate(void);
void settings_load_config(void);
uint8_t settings_save_config(void);
uint8_t settings_get_animation_config(void);
void settings_set_animation_config(uint8_t value);
#endif

Some files were not shown because too many files have changed in this diff Show More