From 81f6dd24733e9c4f032c0c177081ddff9eaf276a Mon Sep 17 00:00:00 2001 From: Jason Navarrete Date: Mon, 28 Aug 2023 21:33:36 -0700 Subject: [PATCH 01/25] Update cli.md Installing ninja fails without updating keys. --- docs/cli.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli.md b/docs/cli.md index 4bcf5e0..c7cf339 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -32,7 +32,7 @@ Using ProxSpace to build the CLI is the easiest and most comfortable way to get 8. Now go into the newly created folder with `cd ChameleonUltra/software/src` -9. Prepare for package installation with `pacman-key --init; pacman-key --populate; pacman -S msys2-keyring --noconfirm` +9. Prepare for package installation with `pacman-key --init; pacman-key --populate; pacman -S msys2-keyring --noconfirm; pacman-key --refresh` 10. Proceed by installing Ninja with `pacman -S ninja --noconfirm` From f80e7fe14e2eb6827499dbd3ebf8fd1d92d8abb9 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Tue, 29 Aug 2023 13:09:24 +0200 Subject: [PATCH 02/25] doc ble --- docs/troubleshooting.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 5210b98..e4d2a10 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -7,6 +7,15 @@ It has reported that on some devices the electric connection is not good, some g You can try to dismantle very gently the screws and PCB, clean them and put them back in place. Be very careful the screws have been reported to be quite fragile so be gentle with them! +## Difficulties to use BLE + +After BLE pairing, both the phone and ChameleonUltra will save a secret key for encrypted communication. If either party deletes the pairing record, it will result in communication failure. If Bluetooth cannot be connected, clearing the pairing information on the other side can solve the problem: + +* Find the Bluetooth settings in the phone's system settings and cancel pairing with the ChameleonUltra. +* In the CLI of ChameleonUltra, execute the `hw ble bonds clear` command to clear all pairing records. + +Default BLE connect key(passkey) is `123456` + # DFU ## Communication issues between CLI and Chameleon From c70165fafa68e6f0fc48fde5386d4fec01eac72a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 30 Aug 2023 00:05:50 +0200 Subject: [PATCH 03/25] bugreport templates --- .github/ISSUE_TEMPLATE/bug_report.md | 50 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 +++ .github/ISSUE_TEMPLATE/feature_request.md | 25 ++++++++++++ README.md | 6 +++ 4 files changed, 86 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..0e4d53a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,50 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +***Things to try before submitting a bug report*** + +* read the [troubleshooting guide](https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/docs/troubleshooting.md) +* check existing [issues](https://github.com/RfidResearchGroup/ChameleonUltra/issues) +* use the latest firmware and CLI +* for issues specific to another client than the Python CLI, use the corresponding issue tracker. E.g. [here](https://github.com/GameTec-live/ChameleonUltraGUI/issues) for the ChameleonUltraGUI + +***Compilation problems*** +Try compiling with verbose. Use `make VERBOSE=1` for the firmware and the software/src tools. +Include the verbose compilation logs. + +***flashing problems*** +Have you followed the instructions properly? + + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior. +Explain it as you would do to someone not familiar with the problematic feature. +What is the abnormal behavior you observed? +E.g. +1. Connect '....' +2. Execute '....' +3. Press button '....' +4. See error '....' + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. For console text and logs, better to dump them as text than image. Attach files if too long. + +**Host (please complete the following information):** + - OS and version + - for compilation issues, the toolchain version + - inside CLI run `hw version` and paste the output here + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..73e99bb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Official channels Chameleon Ultra Community + url: https://github.com/RfidResearchGroup/ChameleonUltra#official-channels + about: Got questions? Ask in *official channels*, not in an issue diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..47b511d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,25 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[idea]" +labels: Request, enhancement +assignees: '' + +--- + +Please keep in mind we are still at the infancy of the project and a lot has still to be done. + +Have first a look at the [Whitepaper](https://github.com/RfidResearchGroup/ChameleonUltra/blob/main/docs/technical_whitepaper.md), the Wiki [Roadmap](https://github.com/RfidResearchGroup/ChameleonUltra/wiki/Public-Roadmap) and [Wishlist](https://github.com/RfidResearchGroup/ChameleonUltra/wiki/Wishlist). +No need for creating issues for well known missing supports, we are already aware :) + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/README.md b/README.md index c867134..b3ebe76 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,10 @@ Read the [available documentation](docs/README.md). * [Downloading and compiling the official CLI](https://www.youtube.com/watch?v=VGpAeitNXH0) * [Downloading ChameleonUltraGUI](https://www.youtube.com/watch?v=rHH7iqbX3nY) +# Official channels +Where do you find the community? + +* [RFID Hacking community discord server](https://t.ly/d4_C) + * Software/chameleon-dev for firmware and clients development discussions + * Devices/chameleon-ultra for usage discussions From d57a24073b77c6f505f66c77e79ae0150daff4de Mon Sep 17 00:00:00 2001 From: Andrea Draghetti Date: Wed, 30 Aug 2023 11:48:29 +0200 Subject: [PATCH 04/25] Update quickstart.md --- docs/quickstart.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index f309ae9..a7b66d0 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -4,13 +4,11 @@ Quickly get up and running with your Chameleon and no technical skill 1. Download GUI - - [Playstore ](https://play.google.com/store/apps/details?id=io.chameleon.ultra)/ [APK](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/apk.zip) - + - [Playstore](https://play.google.com/store/apps/details?id=io.chameleon.ultra)/ [APK](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/apk.zip) - [Windows](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows-installer.zip) - - [Linux](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/linux.zip) - - [IOS](https://apps.apple.com/at/app/mtools-ble-rfid-reader/id1531345398)(MTools) + - [MacOS](https://apps.apple.com/it/app/chameleon-ultra-gui/id6462919364?mt=12) 2. Plug in or connect via Bluetooth your Chameleon From 327e6c06e5a64d69a350d64d94b7284f3ecfb2f8 Mon Sep 17 00:00:00 2001 From: Foxushka <135865149+Foxushka@users.noreply.github.com> Date: Wed, 30 Aug 2023 13:40:14 +0000 Subject: [PATCH 05/25] Fix links and correct OS namings --- docs/quickstart.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index a7b66d0..3d0104f 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -2,18 +2,16 @@ Quickly get up and running with your Chameleon and no technical skill -1. Download GUI +1. Download any of those applications - - [Playstore](https://play.google.com/store/apps/details?id=io.chameleon.ultra)/ [APK](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/apk.zip) - - [Windows](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows-installer.zip) + - [Google Play](https://play.google.com/store/apps/details?id=io.chameleon.ultra) / [APK](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/apk.zip) + - [Windows](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows-installer.zip) ([or without installer](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows.zip)) - [Linux](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/linux.zip) - - [IOS](https://apps.apple.com/at/app/mtools-ble-rfid-reader/id1531345398)(MTools) - - [MacOS](https://apps.apple.com/it/app/chameleon-ultra-gui/id6462919364?mt=12) + - [iOS](https://apps.apple.com/app/mtools-ble-rfid-reader/id1531345398) (MTools) + - [macOS](https://apps.apple.com/app/chameleon-ultra-gui/id6462919364) -2. Plug in or connect via Bluetooth your Chameleon +2. Connect your Chameleon via USB or BLE -3. Open GUI +3. Open application 4. Enjoy - - From 80a7054c7cf8e3c5b2a7ec2b226307bbfae1f018 Mon Sep 17 00:00:00 2001 From: jimmytai Date: Wed, 30 Aug 2023 23:05:31 +0800 Subject: [PATCH 06/25] Docs: protocol --- docs/images/protocol-packet.png | Bin 0 -> 25723 bytes docs/protocol.md | 13 ++++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 docs/images/protocol-packet.png diff --git a/docs/images/protocol-packet.png b/docs/images/protocol-packet.png new file mode 100644 index 0000000000000000000000000000000000000000..98372b5e33a16b31b5565c41ba1b9d5d8eda832e GIT binary patch literal 25723 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 U>Uhi=RnXNQp00i_>zopr08SACmH+?% literal 0 HcmV?d00001 diff --git a/docs/protocol.md b/docs/protocol.md index 7b1a6a2..f7643ef 100644 --- a/docs/protocol.md +++ b/docs/protocol.md @@ -6,11 +6,18 @@ The communication with the application is not the easiest but is structured as follows: -`MAGIC BYTE(0x11) LRC(Magic Byte) COMMAND STATUS(0x00) DATA LRC(COMMAND + STATUS + DATA)` +![](images/protocol-packet.png) -You build the Packet by first adding 0x11, this is the "Magic Byte" to say that there is something coming. This is followed by the LRC ([**L**ongitudinal **R**edundancy **C**heck](https://en.wikipedia.org/wiki/Longitudinal_redundancy_check)) of the "Magic Byte". Then you put in the command in [Big Endian](https://en.wikipedia.org/wiki/Endianness). Each command gets assigned a unique number (e.g. `factoryReset(1020)`), this is what you are sending to the device. Append the status, also in Big Endian. The status is always 0x00. Then you add your Data, this could be anything, for example sending the card keys when reading a block. +- **SOF**: `1 Byte`, the "Magic Byte" represent the start of a packet, must be `0x11`. +- **LRC1**: `1 Byte`, the LRC ([**L**ongitudinal **R**edundancy **C**heck](https://en.wikipedia.org/wiki/Longitudinal_redundancy_check)) of the `SOF`, must be `0xEF`. +- **CMD**: `2 Bytes` in unsigned [Big Endian](https://en.wikipedia.org/wiki/Endianness) format, each command have been assigned a unique number (e.g. `factoryReset(1020)`), this is what you are sending to the device. +- **STATUS**: `2 Bytes` in unsigned [Big Endian](https://en.wikipedia.org/wiki/Endianness) format. If the direction is from APP to hardware, the status is always `0x0000`. If the direction is from hardware to APP, the status is the result of the command. +- **LEN**: `2 Bytes` in unsigned [Big Endian](https://en.wikipedia.org/wiki/Endianness) format, the length of the data, maximum is `512`. +- **LRC2**: `1 Byte`, the LRC ([**L**ongitudinal **R**edundancy **C**heck](https://en.wikipedia.org/wiki/Longitudinal_redundancy_check)) of the `CMD`, `STATUS` and `LEN`. +- **DATA**: `LEN Bytes`, the data to send or receive, maximum is `512 Bytes`. This could be anything, for example you should sending key type, block number, and the card keys when reading a block. +- **LRC3**: `1 Byte`, the LRC ([**L**ongitudinal **R**edundancy **C**heck](https://en.wikipedia.org/wiki/Longitudinal_redundancy_check)) of the `DATA`. -For receiving, it is the exact same in reverse. +The total length of the packet is `LEN + 10` Bytes. For receiving, it is the exact same format. ## Packet payloads From 51b15ea90deb909c2051312aca0aa4ffac3337fa Mon Sep 17 00:00:00 2001 From: Foxushka <135865149+Foxushka@users.noreply.github.com> Date: Wed, 30 Aug 2023 18:49:05 +0000 Subject: [PATCH 07/25] Fix Chameleon crashes in BLE pairing --- firmware/application/src/ble_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/firmware/application/src/ble_main.c b/firmware/application/src/ble_main.c index ba09a8e..bca49a2 100644 --- a/firmware/application/src/ble_main.c +++ b/firmware/application/src/ble_main.c @@ -708,11 +708,11 @@ void saadc_event_handler(nrf_drv_saadc_evt_t const *p_event) { // if battery service is notification enable, we can send msg to device. err_code = ble_bas_battery_level_update(&m_bas, percentage_batt_lvl, BLE_CONN_HANDLE_ALL); if ((err_code != NRF_SUCCESS) && - (err_code != NRF_ERROR_INVALID_STATE) && - (err_code != NRF_ERROR_RESOURCES) && - (err_code != NRF_ERROR_BUSY) && - (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) - ) { + (err_code != NRF_ERROR_INVALID_STATE) && + (err_code != NRF_ERROR_RESOURCES) && + (err_code != NRF_ERROR_BUSY) && + (err_code != NRF_ERROR_FORBIDDEN) && + (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) { APP_ERROR_HANDLER(err_code); } From 93141e3e6c2a1256f00736c72fe885c34d45cf66 Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:28:38 +0300 Subject: [PATCH 08/25] Update firmware.md explanation on write modes provided by GameTec_live --- docs/firmware.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/firmware.md b/docs/firmware.md index 851a2d0..ff8f60c 100644 --- a/docs/firmware.md +++ b/docs/firmware.md @@ -102,6 +102,11 @@ The Chameleon also shows the following LED effects: The device enters sleep mode after about 5s unless it is plugged in USB or if a client is connected over BLE. You can use the buttons to wake it up again. You can also press quickly a button during the sleep animation to keep the device awake. +## Write Modes +- Normal: Behaves like any norml card +- Decline: Read only card +- Decive: Accept write commands but dont change any data (reader thinks write was sucesful but when reading nothing changed) +- Shadow: Accept writes but revert when device goes to sleep (reader can read and write like a normal card but it reverts when the chameleon goes to sleep) ## The SoftDevice From 4fcc2f565edb8d2c10e7f8ff23feb43022d68f3e Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Fri, 1 Sep 2023 12:45:42 +0300 Subject: [PATCH 09/25] Update firmware.md --- docs/firmware.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/firmware.md b/docs/firmware.md index ff8f60c..3933835 100644 --- a/docs/firmware.md +++ b/docs/firmware.md @@ -103,7 +103,7 @@ The Chameleon also shows the following LED effects: The device enters sleep mode after about 5s unless it is plugged in USB or if a client is connected over BLE. You can use the buttons to wake it up again. You can also press quickly a button during the sleep animation to keep the device awake. ## Write Modes -- Normal: Behaves like any norml card +- Normal: Behaves like any normal card - Decline: Read only card - Decive: Accept write commands but dont change any data (reader thinks write was sucesful but when reading nothing changed) - Shadow: Accept writes but revert when device goes to sleep (reader can read and write like a normal card but it reverts when the chameleon goes to sleep) From 5e1a50200506b0ddd1f415372b4f10b2643d3a06 Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Fri, 1 Sep 2023 13:01:03 +0300 Subject: [PATCH 10/25] Update chameleonultragui.md based on cyber.vi.king's and gametec_live's comment on this --- docs/chameleonultragui.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/chameleonultragui.md b/docs/chameleonultragui.md index e69de29..0414c93 100644 --- a/docs/chameleonultragui.md +++ b/docs/chameleonultragui.md @@ -0,0 +1,6 @@ +## How to use MFKEY32 + +- set slot to mifare classic (by uploading an empty dump) +- enable mfkey32 for that slot (toggle in slot settings) +- select slot and present ultra repeatedly to the reader in order to collect nonces +- after collecting some nonces, go back into slot settings and click recover keys From 65845fd7f57f33dfcfc5069c155a5cf8d2ccec70 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 1 Sep 2023 12:24:19 +0200 Subject: [PATCH 11/25] Update docs/firmware.md --- docs/firmware.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/firmware.md b/docs/firmware.md index 3933835..7edf745 100644 --- a/docs/firmware.md +++ b/docs/firmware.md @@ -103,10 +103,10 @@ The Chameleon also shows the following LED effects: The device enters sleep mode after about 5s unless it is plugged in USB or if a client is connected over BLE. You can use the buttons to wake it up again. You can also press quickly a button during the sleep animation to keep the device awake. ## Write Modes -- Normal: Behaves like any normal card -- Decline: Read only card -- Decive: Accept write commands but dont change any data (reader thinks write was sucesful but when reading nothing changed) -- Shadow: Accept writes but revert when device goes to sleep (reader can read and write like a normal card but it reverts when the chameleon goes to sleep) +- **Normal**: Behaves like any normal card +- **Denied**: Read-only card, send NACK to write attempts +- **Deceive**: Accepts write commands but don't change any data (reader thinks write was successful but when reading back, nothing changed) +- **Shadow**: Accepts writes but reverts changes when device goes to sleep (reader can read and write like a normal card but changes are kept in RAM and are lost when the chameleon goes to sleep) ## The SoftDevice From 7506e64bc83438fa5e5dfd2f213ebfc70659ce07 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Fri, 1 Sep 2023 20:16:46 +0200 Subject: [PATCH 12/25] Mods --- docs/README.md | 22 ++++++++++++---------- docs/modding.md | 3 +++ 2 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 docs/modding.md diff --git a/docs/README.md b/docs/README.md index 918abb5..18ff5b3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,22 +4,24 @@ This guide goal is to guide you through setting up and using your Chameleon Ultr This Guide is split up into multiple "subguides": -- ["Whitepaper"](./technical_whitepaper.md): Discover what the Chameleon Ultra is capable of +- [Whitepaper](./technical_whitepaper.md): Discover what the Chameleon Ultra is capable of -- ["Hardware"](./hardware.md): Learn to know the hardware of your Chameleon +- [Hardware](./hardware.md): Learn to know the hardware of your Chameleon -- ["Firmware"](./firmware.md): Your Chameleon runs a firmware, learn what it can do and how to use it +- [Firmware](./firmware.md): Your Chameleon runs a firmware, learn what it can do and how to use it -- ["CLI"](./cli.md): The official way to control your Chameleon is via the **C**ommand **L**ine **I**nterface (CLI) . Learn how to install and master the CLI. +- [CLI](./cli.md): The official way to control your Chameleon is via the **C**ommand **L**ine **I**nterface (CLI) . Learn how to install and master the CLI. -- ["GUIs"](./gui.md): Some people also develop **G**raphical **U**ser **I**nterfaces (GUIs), these may be a good start for people that do not want to deal with a CLI. +- [GUIs](./gui.md): Some people also develop **G**raphical **U**ser **I**nterfaces (GUIs), these may be a good start for people that do not want to deal with a CLI. -- ["Troubleshooting"](./troubleshooting.md): For when things go wrong, here are some common tips to maybe fix whatever issue you might have. +- [Troubleshooting](./troubleshooting.md): For when things go wrong, here are some common tips to maybe fix whatever issue you might have. -- ["FAQ"](./faq.md): Frequently asked questions, if you have a question, it might already be answered here. +- [FAQ](./faq.md): Frequently Asked Questions, if you have a question, it might already be answered here. -- ["Quickstart"](./quickstart.md): for the impatient people to just get you up and running with anything. +- [Quickstart](./quickstart.md): for the impatient people to just get you up and running with anything. -- ["Development"](./development.md): for all developers. This covers how to build firmware from source and set up a development environment. +- [Development](./development.md): for all developers. This covers how to build firmware from source and set up a development environment. -- ["Protocol"](./protocol.md): the gory details of the communication protocol, useful if you want to develop your own client. +- [Protocol](./protocol.md): the gory details of the communication protocol, useful if you want to develop your own client. + +- [Modding](./modding.md): third party moddings worth mentioning. diff --git a/docs/modding.md b/docs/modding.md new file mode 100644 index 0000000..53195ef --- /dev/null +++ b/docs/modding.md @@ -0,0 +1,3 @@ +# Third party moddings + +* [ChameleonUltra Keyring](https://www.printables.com/model/552739-chameleonultra-keyring), an extended frame for ChameleonUltra with a sturdy keyring loop. From f134b4f16ae1a7952d4d6318e99418004163ee08 Mon Sep 17 00:00:00 2001 From: dxl <64101226@qq.com> Date: Sun, 3 Sep 2023 03:38:23 +0800 Subject: [PATCH 13/25] Mfc 1k Full emulation (not UID only) with OEM readers bugs fixed. --- .../application/src/rfid/nfctag/hf/nfc_14a.c | 36 +++++++++++++++++-- .../application/src/rfid/nfctag/hf/nfc_mf1.h | 2 +- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c index c293a84..fb016a3 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c +++ b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c @@ -295,7 +295,7 @@ uint8_t nfc_tag_14a_unwrap_frame(const uint8_t *pbtFrame, const size_t szFrameBi * @param[in] appendCrc Whether to send the byte flow, automatically send the CRC16 verification automatically */ void nfc_tag_14a_tx_bytes(uint8_t *data, uint32_t bytes, bool appendCrc) { - NFC_14A_TX_BYTE_CORE(data, bytes, appendCrc, NRF_NFCT_FRAME_DELAY_MODE_WINDOW); + NFC_14A_TX_BYTE_CORE(data, bytes, appendCrc, NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID); } /**@brief The function of sending the byte flow, this implementation automatically sends SOF @@ -316,6 +316,7 @@ void nfc_tag_14a_tx_bytes_delay_freerun(uint8_t *data, uint32_t bytes, bool appe */ #define NFC_14A_TX_BITS_CORE(bits, mode) \ do { \ + nrf_nfct_frame_delay_max_set(65535); \ NRF_NFCT->PACKETPTR = (uint32_t)(m_nfc_tx_buffer); \ NRF_NFCT->TXD.AMOUNT = bits; \ NRF_NFCT->INTENSET = (NRF_NFCT_INT_TXFRAMESTART_MASK | NRF_NFCT_INT_TXFRAMEEND_MASK); \ @@ -332,7 +333,7 @@ void nfc_tag_14a_tx_bytes_delay_freerun(uint8_t *data, uint32_t bytes, bool appe void nfc_tag_14a_tx_bits(uint8_t *data, uint32_t bits) { m_is_responded = true; memcpy(m_nfc_tx_buffer, data, (bits / 8) + (bits % 8 > 0 ? 1 : 0)); - NFC_14A_TX_BITS_CORE(bits, NRF_NFCT_FRAME_DELAY_MODE_FREERUN); + NFC_14A_TX_BITS_CORE(bits, NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID); } /**@brief The function of sending n bits is implemented, and this implementation is automatically sent SOF @@ -354,7 +355,7 @@ void nfc_tag_14a_tx_nbit(uint8_t data, uint32_t bits) { void nfc_tag_14a_tx_nbit_delay_window(uint8_t data, uint32_t bits) { m_is_responded = true; m_nfc_tx_buffer[0] = data; - NFC_14A_TX_BITS_CORE(bits, NRF_NFCT_FRAME_DELAY_MODE_WINDOW); + NFC_14A_TX_BITS_CORE(bits, NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID); } /** @@ -578,6 +579,31 @@ void nfc_tag_14a_data_process(uint8_t *p_data) { } } +static inline void nfc_core_reset(void) +{ + uint32_t int_enabled = nrf_nfct_int_enable_get(); + + // Reset the NFCT peripheral. + *(volatile uint32_t *)0x40005FFC = 0; + *(volatile uint32_t *)0x40005FFC; + *(volatile uint32_t *)0x40005FFC = 1; + + // Restore parameter settings after the reset of the NFCT peripheral. + nrf_nfct_frame_delay_max_set(0x00001000UL); + // Use Window Grid frame delay mode. + nrf_nfct_frame_delay_mode_set(NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID); + + // Restore interrupts. + nrf_nfct_int_enable(int_enabled); +} + +static inline void nfc_fdt_reset(void) { + // STOP TX + *(volatile uint32_t *)0x40005010 = 0x01; + // Reset fdt max + nrf_nfct_frame_delay_max_set(0x00001000UL); +} + extern bool g_usb_led_marquee_enable; /** @@ -619,6 +645,8 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) { TAG_FIELD_LED_OFF() m_tag_state_14a = NFC_TAG_STATE_14A_IDLE; + nfc_core_reset(); + NRF_LOG_INFO("HF FIELD LOST"); break; } @@ -648,6 +676,7 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) { nfc_tag_14a_data_process(m_nfc_rx_buffer); // The above prompt tells us that when we do not need to reply to the card reader, we need to manually enable it if (!m_is_responded) { + nfc_fdt_reset(); NRFX_NFCT_RX_BYTES } break; @@ -661,6 +690,7 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) { if (m_is_responded) { NRF_LOG_ERROR("NRFX_NFCT_ERROR_FRAMEDELAYTIMEOUT: %d", m_tag_state_14a); } + nfc_fdt_reset(); break; } case NRFX_NFCT_ERROR_NUM: { diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h b/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h index bc6e561..97041dc 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h +++ b/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h @@ -5,7 +5,7 @@ // Exchange space for time. // Fast simulate enable(Implement By ChameleonMini Repo) -#define NFC_MF1_FAST_SIM +// #define NFC_MF1_FAST_SIM #define NFC_TAG_MF1_DATA_SIZE 16 #define NFC_TAG_MF1_FRAME_SIZE (NFC_TAG_MF1_DATA_SIZE + NFC_TAG_14A_CRC_LENGTH) From d50e1437b78e8f1763cb45bc1d9fd3e57dbbe90d Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 2 Sep 2023 22:22:52 +0200 Subject: [PATCH 14/25] changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bccdfdb..1e0b380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ 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] + - Fixed MFC emulation issues with OEM readers, also temporarily disabling NFC_MF1_FAST_SIM (@xianglin1998) + - Fixed Chameleon crash during BLE pairing (@Foxushka) - Fixed CLI takes into account Lite refusing to enter Reader mode (@doegox) - Security BLE implemented (@xianglin1998) - Added `hw settings blekey` to get and set ble connect key (@xianglin1998) @@ -19,7 +21,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Added offline copy EM card uid for btnpress (@nemanjan00) - Added offline copy ic card uid for btnpress (@xianglin1998) - Added `hw settings btnpress` to get and set button press function (@xianglin1998) - - Added `hw battery` to get battery informartion (@xianglin1998) + - Added `hw battery` to get battery information (@xianglin1998) - Added `hw slot delete` to delete HF or LF out of a HF+LF slot (@augustozanellato) - Changed CLI prompt autocompletion, saved history and internal cmd registration (@szymex73) - Fixed SDK NFC IRQ handler busy loop (@doegox) From 76168621b4b4e56de275eab8c9621f22a1caf54e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sat, 2 Sep 2023 22:24:15 +0200 Subject: [PATCH 15/25] style --- firmware/application/src/app_cmd.c | 10 ++-- firmware/application/src/app_main.c | 2 +- firmware/application/src/ble_main.c | 60 ++++++++----------- firmware/application/src/ble_main.h | 2 +- .../application/src/rfid/nfctag/hf/nfc_14a.c | 3 +- firmware/application/src/sdk_config.h | 12 ++-- firmware/application/src/settings.c | 6 +- firmware/application/src/settings.h | 4 +- firmware/application/src/utils/fds_util.c | 4 +- software/script/chameleon_cli_unit.py | 6 +- software/script/chameleon_cmd.py | 11 ++-- 11 files changed, 55 insertions(+), 65 deletions(-) diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index be95a68..26a442d 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -755,11 +755,11 @@ data_frame_tx_t *cmd_processor_get_enabled_slots(uint16_t cmd, uint16_t status, data_frame_tx_t *cmd_processor_get_ble_connect_key(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { return data_frame_make( - cmd, - STATUS_DEVICE_SUCCESS, - BLE_CONNECT_KEY_LEN_MAX, // 6 - settings_get_ble_connect_key() // Get key point from config - ); + cmd, + STATUS_DEVICE_SUCCESS, + BLE_CONNECT_KEY_LEN_MAX, // 6 + settings_get_ble_connect_key() // Get key point from config + ); } data_frame_tx_t *cmd_processor_set_ble_connect_key(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { diff --git a/firmware/application/src/app_main.c b/firmware/application/src/app_main.c index d398149..de53043 100644 --- a/firmware/application/src/app_main.c +++ b/firmware/application/src/app_main.c @@ -775,7 +775,7 @@ int main(void) { power_management_init(); // Power management initialization usb_cdc_init(); // USB cdc emulation initialization ble_slave_init(); // Bluetooth protocol stack initialization - + rng_drv_and_srand_init(); // Random number generator initialization bsp_timer_init(); // Initialize timeout timer bsp_timer_start(); // Start BSP TIMER and prepare it for processing business logic diff --git a/firmware/application/src/ble_main.c b/firmware/application/src/ble_main.c index bca49a2..112d277 100644 --- a/firmware/application/src/ble_main.c +++ b/firmware/application/src/ble_main.c @@ -105,7 +105,7 @@ static ble_opt_t m_static_pin_option; * * @details This function will set up the ble connect passkey. */ -void set_ble_connect_key(uint8_t* key) { +void set_ble_connect_key(uint8_t *key) { static uint8_t passkey[BLE_CONNECT_KEY_LEN_MAX]; memcpy(passkey, key, BLE_CONNECT_KEY_LEN_MAX); m_static_pin_option.gap_opt.passkey.p_passkey = passkey; @@ -442,7 +442,7 @@ static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) { // err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); // APP_ERROR_CHECK(err_code); break; - + case BLE_GAP_EVT_PASSKEY_DISPLAY: { char passkey[BLE_GAP_PASSKEY_LEN + 1]; memcpy(passkey, p_ble_evt->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN); @@ -556,8 +556,7 @@ static void advertising_init(void) { /**@brief Clear bond information from persistent storage. */ -void delete_bonds_all(void) -{ +void delete_bonds_all(void) { ret_code_t err_code; NRF_LOG_INFO("Erase bonds!"); @@ -570,8 +569,7 @@ void delete_bonds_all(void) * * @param[in] skip Filter passed to @ref pm_peer_id_list. */ -static void whitelist_set(pm_peer_id_list_skip_t skip) -{ +static void whitelist_set(pm_peer_id_list_skip_t skip) { pm_peer_id_t peer_ids[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; uint32_t peer_id_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; @@ -586,15 +584,11 @@ static void whitelist_set(pm_peer_id_list_skip_t skip) /**@brief Function for starting advertising. */ -void advertising_start(bool erase_bonds) -{ - if (erase_bonds == true) - { +void advertising_start(bool erase_bonds) { + if (erase_bonds == true) { delete_bonds_all(); // Advertising is started by PM_EVT_PEERS_DELETE_SUCCEEDED event. - } - else - { + } else { whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR); ret_code_t ret = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); @@ -605,8 +599,7 @@ void advertising_start(bool erase_bonds) /** * @brief Function for stop advertising. */ -void advertising_stop(void) -{ +void advertising_stop(void) { sd_ble_gap_adv_stop(m_advertising.adv_handle); } @@ -614,14 +607,12 @@ void advertising_stop(void) * * @param[in] p_evt Peer Manager event. */ -static void pm_evt_handler(pm_evt_t const * p_evt) -{ +static void pm_evt_handler(pm_evt_t const *p_evt) { pm_handler_on_pm_evt(p_evt); pm_handler_disconnect_on_sec_failure(p_evt); pm_handler_flash_clean(p_evt); - switch (p_evt->evt_id) - { + switch (p_evt->evt_id) { case PM_EVT_CONN_SEC_SUCCEEDED: // p_evt->peer_id; break; @@ -631,22 +622,20 @@ static void pm_evt_handler(pm_evt_t const * p_evt) break; case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED: - if ( p_evt->params.peer_data_update_succeeded.flash_changed - && (p_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_BONDING)) - { + if (p_evt->params.peer_data_update_succeeded.flash_changed + && (p_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_BONDING)) { NRF_LOG_INFO("New Bond, add the peer to the whitelist if possible"); // Note: You should check on what kind of white list policy your application should use. whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR); } break; - case PM_EVT_CONN_SEC_CONFIG_REQ: - { - pm_conn_sec_config_t cfg; - cfg.allow_repairing = true; - pm_conn_sec_config_reply(p_evt->conn_handle, &cfg); - } - break; + case PM_EVT_CONN_SEC_CONFIG_REQ: { + pm_conn_sec_config_t cfg; + cfg.allow_repairing = true; + pm_conn_sec_config_reply(p_evt->conn_handle, &cfg); + } + break; default: break; } @@ -654,8 +643,7 @@ static void pm_evt_handler(pm_evt_t const * p_evt) /**@brief Function for the Peer Manager initialization. */ -static void peer_manager_init(void) -{ +static void peer_manager_init(void) { ble_gap_sec_params_t sec_param; ret_code_t err_code; @@ -708,11 +696,11 @@ void saadc_event_handler(nrf_drv_saadc_evt_t const *p_event) { // if battery service is notification enable, we can send msg to device. err_code = ble_bas_battery_level_update(&m_bas, percentage_batt_lvl, BLE_CONN_HANDLE_ALL); if ((err_code != NRF_SUCCESS) && - (err_code != NRF_ERROR_INVALID_STATE) && - (err_code != NRF_ERROR_RESOURCES) && - (err_code != NRF_ERROR_BUSY) && - (err_code != NRF_ERROR_FORBIDDEN) && - (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) { + (err_code != NRF_ERROR_INVALID_STATE) && + (err_code != NRF_ERROR_RESOURCES) && + (err_code != NRF_ERROR_BUSY) && + (err_code != NRF_ERROR_FORBIDDEN) && + (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) { APP_ERROR_HANDLER(err_code); } diff --git a/firmware/application/src/ble_main.h b/firmware/application/src/ble_main.h index 6c8bec2..49c9edc 100644 --- a/firmware/application/src/ble_main.h +++ b/firmware/application/src/ble_main.h @@ -15,6 +15,6 @@ void advertising_stop(void); void delete_bonds_all(void); void nus_data_response(uint8_t *p_data, uint16_t length); bool is_nus_working(void); -void set_ble_connect_key(uint8_t* key); +void set_ble_connect_key(uint8_t *key); #endif diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c index fb016a3..d608592 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c +++ b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c @@ -579,8 +579,7 @@ void nfc_tag_14a_data_process(uint8_t *p_data) { } } -static inline void nfc_core_reset(void) -{ +static inline void nfc_core_reset(void) { uint32_t int_enabled = nrf_nfct_int_enable_get(); // Reset the NFCT peripheral. diff --git a/firmware/application/src/sdk_config.h b/firmware/application/src/sdk_config.h index 3ee011f..5bddb15 100644 --- a/firmware/application/src/sdk_config.h +++ b/firmware/application/src/sdk_config.h @@ -298,20 +298,20 @@ //========================================================== // NRF_BLE_LESC_ENABLED - Enable LESC Module - + #ifndef NRF_BLE_LESC_ENABLED #define NRF_BLE_LESC_ENABLED 1 #endif // NRF_BLE_LESC_GENERATE_NEW_KEYS - Generate new LESC keys after every pairing attempt. Keys are generated on the auth status event - + #ifndef NRF_BLE_LESC_GENERATE_NEW_KEYS #define NRF_BLE_LESC_GENERATE_NEW_KEYS 1 #endif -// +// //========================================================== // @@ -1380,7 +1380,7 @@ //========================================================== // NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED - Use static memory buffers for context and temporary init buffer. - + // Always recommended when using the nRF HW RNG as the context and temporary buffers are small. Consider disabling if using the CC310 RNG in a RAM constrained application. In this case, memory must be provided to nrf_crypto_rng_init, or it can be allocated internally provided that NRF_CRYPTO_ALLOCATOR does not allocate memory on the stack. @@ -1389,7 +1389,7 @@ #endif // NRF_CRYPTO_RNG_AUTO_INIT_ENABLED - Initialize the RNG module automatically when nrf_crypto is initialized. - + // Automatic initialization is only supported with static or internally allocated context and temporary memory. @@ -1397,7 +1397,7 @@ #define NRF_CRYPTO_RNG_AUTO_INIT_ENABLED 1 #endif -// +// //========================================================== // diff --git a/firmware/application/src/settings.c b/firmware/application/src/settings.c index a37d323..0c02363 100644 --- a/firmware/application/src/settings.c +++ b/firmware/application/src/settings.c @@ -254,15 +254,15 @@ void settings_set_long_button_press_config(char which, uint8_t value) { } } -uint8_t* settings_get_ble_connect_key(void) { +uint8_t *settings_get_ble_connect_key(void) { return config.ble_connect_key; } /** * @brief Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. - * + * * @param key Ble connect key for your device */ -void settings_set_ble_connect_key(uint8_t* key) { +void settings_set_ble_connect_key(uint8_t *key) { memcpy(config.ble_connect_key, key, BLE_CONNECT_KEY_LEN_MAX); } diff --git a/firmware/application/src/settings.h b/firmware/application/src/settings.h index 3ef4364..cdc5f62 100644 --- a/firmware/application/src/settings.h +++ b/firmware/application/src/settings.h @@ -67,6 +67,6 @@ uint8_t settings_get_long_button_press_config(char which); void settings_set_button_press_config(char which, uint8_t value); void settings_set_long_button_press_config(char which, uint8_t value); bool is_settings_button_type_valid(char type); -uint8_t* settings_get_ble_connect_key(void); -void settings_set_ble_connect_key(uint8_t* key); +uint8_t *settings_get_ble_connect_key(void); +void settings_set_ble_connect_key(uint8_t *key); #endif diff --git a/firmware/application/src/utils/fds_util.c b/firmware/application/src/utils/fds_util.c index 9243ee1..9edc639 100644 --- a/firmware/application/src/utils/fds_util.c +++ b/firmware/application/src/utils/fds_util.c @@ -183,11 +183,11 @@ static bool is_peer_manager_record(uint16_t id_or_key) { */ static void fds_evt_handler(fds_evt_t const *p_evt) { // Skip peermanager event - if (is_peer_manager_record(p_evt->write.record_key) + if (is_peer_manager_record(p_evt->write.record_key) || is_peer_manager_record(p_evt->write.file_id) || is_peer_manager_record(p_evt->del.record_key) || is_peer_manager_record(p_evt->del.file_id) - ) { + ) { return; } diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index 28059ba..c55d2f2 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -1445,13 +1445,15 @@ class HWSettingsBLEKeySet(DeviceRequiredUnit): def on_exec(self, args: argparse.Namespace): if len(args.key) != 6: - print(f" - {colorama.Fore.RED}The ble connect key length must be 6{colorama.Style.RESET_ALL}") + print( + f" - {colorama.Fore.RED}The ble connect key length must be 6{colorama.Style.RESET_ALL}") return if re.match(r'[0-9]{6}', args.key): self.cmd.set_ble_connect_key(args.key) print(" - Successfully set ble connect key to settings") else: - print(f" - {colorama.Fore.RED}Only 6 ASCII characters from 0 to 9 are supported.{colorama.Style.RESET_ALL}") + print( + f" - {colorama.Fore.RED}Only 6 ASCII characters from 0 to 9 are supported.{colorama.Style.RESET_ALL}") @hw_settings_ble_key.command('get', 'Get the ble connect key') diff --git a/software/script/chameleon_cmd.py b/software/script/chameleon_cmd.py index 9bb4b13..d661f61 100644 --- a/software/script/chameleon_cmd.py +++ b/software/script/chameleon_cmd.py @@ -801,7 +801,7 @@ class ChameleonCMD: 0x00, bytearray([button, function]) ) - + @expect_response(chameleon_status.Device.STATUS_DEVICE_SUCCESS) def set_ble_connect_key(self, key: str): """ @@ -812,25 +812,26 @@ class ChameleonCMD: # check key length if (len(data_bytes) != 6): raise ValueError("The ble connect key length must be 6") - + return self.device.send_cmd_sync( DATA_CMD_SET_BLE_CONNECT_KEY_CONFIG, - 0x00, + 0x00, data_bytes ) - + def get_ble_connect_key(self): """ Get config of ble connect key """ return self.device.send_cmd_sync(DATA_CMD_GET_BLE_CONNECT_KEY_CONFIG, 0x00, None) - + def delete_ble_all_bonds(self): """ From peer manager delete all bonds. """ return self.device.send_cmd_sync(DATA_CMD_DELETE_ALL_BLE_BONDS, 0x00, None) + if __name__ == '__main__': # connect to chameleon dev = chameleon_com.ChameleonCom() From c9c3ad1d7af8db93bdff884e3fcfdc452129d596 Mon Sep 17 00:00:00 2001 From: "paul.73" <42212032+spp2000@users.noreply.github.com> Date: Sun, 3 Sep 2023 13:15:24 +0200 Subject: [PATCH 16/25] Chameleon Lite emulation bug fixed --- firmware/application/src/rfid/nfctag/hf/nfc_14a.c | 1 - 1 file changed, 1 deletion(-) diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c index d608592..b2fb7e1 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c +++ b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c @@ -689,7 +689,6 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) { if (m_is_responded) { NRF_LOG_ERROR("NRFX_NFCT_ERROR_FRAMEDELAYTIMEOUT: %d", m_tag_state_14a); } - nfc_fdt_reset(); break; } case NRFX_NFCT_ERROR_NUM: { From 4bdec10538c63aeca926c930ac10191a36a3476f Mon Sep 17 00:00:00 2001 From: "paul.73" <42212032+spp2000@users.noreply.github.com> Date: Sun, 3 Sep 2023 13:16:01 +0200 Subject: [PATCH 17/25] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e0b380..f1e9ace 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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] + - ChameleonLite emulation bug fixed (@spp2000) - Fixed MFC emulation issues with OEM readers, also temporarily disabling NFC_MF1_FAST_SIM (@xianglin1998) - Fixed Chameleon crash during BLE pairing (@Foxushka) - Fixed CLI takes into account Lite refusing to enter Reader mode (@doegox) From d928ab22851b158f4d25843a3cce04256ce268b2 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Sun, 3 Sep 2023 15:41:19 +0200 Subject: [PATCH 18/25] docs --- docs/chameleonultragui.md | 21 +++++++++++++++------ docs/gui.md | 2 +- docs/quickstart.md | 11 ++++++----- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/chameleonultragui.md b/docs/chameleonultragui.md index 0414c93..5e714f4 100644 --- a/docs/chameleonultragui.md +++ b/docs/chameleonultragui.md @@ -1,6 +1,15 @@ -## How to use MFKEY32 - -- set slot to mifare classic (by uploading an empty dump) -- enable mfkey32 for that slot (toggle in slot settings) -- select slot and present ultra repeatedly to the reader in order to collect nonces -- after collecting some nonces, go back into slot settings and click recover keys +## Get ChameleonUltraGUI + +- [on Google Play](https://play.google.com/store/apps/details?id=io.chameleon.ultra) / [APK](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/apk.zip) +- [on iOS](https://apps.apple.com/dk/app/chameleon-ultra-gui/id6462919364) +- [on Windows](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows-installer.zip) ([or without installer](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows.zip)) +- [on Linux](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/linux.zip) +- [on macOS](https://apps.apple.com/app/chameleon-ultra-gui/id6462919364) + + +## How to use MFKEY32 + +- set slot to mifare classic (by uploading an empty dump) +- enable mfkey32 for that slot (toggle in slot settings) +- select slot and present ultra repeatedly to the reader in order to collect nonces +- after collecting some nonces, go back into slot settings and click recover keys diff --git a/docs/gui.md b/docs/gui.md index 9a62aba..5ec164e 100644 --- a/docs/gui.md +++ b/docs/gui.md @@ -4,4 +4,4 @@ There are multiple GUIs to control your Chameleon, two are featured in this docu - [Chameleon Ultra GUI](./chameleonultragui.md) ([github](https://github.com/GameTec-live/ChameleonUltraGUI)) -- [MTools](https://shop.mtoolstec.com/mifare-classic-tool-for-ios) +- [MTools for iOS](https://shop.mtoolstec.com/mifare-classic-tool-for-ios) diff --git a/docs/quickstart.md b/docs/quickstart.md index 3d0104f..7e9cf90 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -4,11 +4,12 @@ Quickly get up and running with your Chameleon and no technical skill 1. Download any of those applications - - [Google Play](https://play.google.com/store/apps/details?id=io.chameleon.ultra) / [APK](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/apk.zip) - - [Windows](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows-installer.zip) ([or without installer](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows.zip)) - - [Linux](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/linux.zip) - - [iOS](https://apps.apple.com/app/mtools-ble-rfid-reader/id1531345398) (MTools) - - [macOS](https://apps.apple.com/app/chameleon-ultra-gui/id6462919364) + - [ChameleonUltraGUI on Google Play](https://play.google.com/store/apps/details?id=io.chameleon.ultra) / [APK](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/apk.zip) + - [ChameleonUltraGUI on iOS](https://apps.apple.com/dk/app/chameleon-ultra-gui/id6462919364) + - [ChameleonUltraGUI on Windows](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows-installer.zip) ([or without installer](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/windows.zip)) + - [ChameleonUltraGUI on Linux](https://nightly.link/GameTec-live/ChameleonUltraGUI/workflows/buildapp/main/linux.zip) + - [ChameleonUltraGUI on macOS](https://apps.apple.com/app/chameleon-ultra-gui/id6462919364) + - [MTools on iOS](https://apps.apple.com/app/mtools-ble-rfid-reader/id1531345398) 2. Connect your Chameleon via USB or BLE From 9af1c4330cbd0433976d6688d8d10970dd4ae071 Mon Sep 17 00:00:00 2001 From: dxl <64101226@qq.com> Date: Mon, 4 Sep 2023 18:29:59 +0800 Subject: [PATCH 19/25] Delete unused function --- firmware/application/src/app_cmd.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index 26a442d..fca485e 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -223,23 +223,6 @@ data_frame_tx_t *cmd_processor_mf1_darkside_acquire(uint16_t cmd, uint16_t statu return data_frame_make(cmd, status, length, data); } -data_frame_tx_t *cmd_processor_detect_nested_dist(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { - NestedDist nd; - if (length == 8) { - status = nested_distance_detect(data[1], data[0], &data[2], &nd); - if (status == HF_TAG_OK) { - length = sizeof(NestedDist); - data = (uint8_t *)(&nd); - } else { - length = 0; - } - } else { - status = STATUS_PAR_ERR; - length = 0; - } - return data_frame_make(cmd, status, 0, NULL); -} - data_frame_tx_t *cmd_processor_mf1_nt_distance(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { NestedDist nd; if (length == 8) { From 5a9ca62d2a18163ba8cd819e8214fec4df461f9e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Mon, 4 Sep 2023 23:16:19 +0200 Subject: [PATCH 20/25] doc --- docs/cli.md | 43 +++++++++++++++++++++++++++++++++-------- docs/troubleshooting.md | 8 ++++++-- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/docs/cli.md b/docs/cli.md index c7cf339..13428a0 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -118,16 +118,43 @@ When in the CLI, plug in your Chameleon and connect with `hw connect`. If autode ### Common activities -- Change slot: hw slot change -s [1-8] +- Connect to the CLI: `hw connect` +- Change slot: `hw slot change -s [1-8]` *More examples coming soon* -### Available Commands +### MFKEY32v2 walk-through +Make sure to be in the `software/` directory and run the Python CLI from there. -In `()` is the argument description, `[]` are possible entries for that argument (eg `[1-8]`) +- 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 -s8 -t3` +- Init the slot content: `hw slot init -s8 -t3` + - or load an existing dump and set UID and anticollision data, cf `hf mf eload -h` and `hf mf sim -h` +- Enable the slot: `hw slot enable -s8 -e1` +- Change to the new slot: `hw slot change -s8` +- Activate the detection: `hf detection enable -e1` -| Command | Arguments | Description | -|:----------------:|:-------------------------------------------------------------------------:|:-----------------------------------------:| -| `hw factory_reset` | `--i-know-what-im-doing` (Make sure you really want to wipe your Chameleon) | Returns the Chameleon to factory settings | -| | | | -| | | | +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 detection count` + - We need 2 nonces per key to recover +- Recover the key(s) based on the collected nonces: `hf detection decrypt`. Output example: +``` + - MF1 detection log count = 6, start download. + - Download done (144bytes), start parse and decrypt + - Detection log for uid [DEADBEEF] + > Block 0 detect log decrypting... + > Block 1 detect log decrypting... + > Result --------------------------- + > Block 0, A key result: ['a0a1a2a3a4a5', 'aabbccddeeff'] + > Block 1, A key result: ['010203040506'] + +``` + +- To clean the logged detection nonces: `hf detection enable -e0` then `hf detection enable -e1` + + + +*More examples coming soon* diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index e4d2a10..047ee40 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -1,9 +1,13 @@ # Hardware +## Difficulties to get emulation working properly + +Try with waking up the Chameleon by pressing a button before presenting it to the reader. Try with keeping some 2-3 cm distance to the reader. + ## Difficulties to get the LF working properly The LF antenna is on a second PCB attached to the main PCB via little screws which also serve as electric connection. -It has reported that on some devices the electric connection is not good, some glue or resin residues mai interfere. +It has reported that on some devices the electric connection is not good, some glue or resin residues may interfere. You can try to dismantle very gently the screws and PCB, clean them and put them back in place. Be very careful the screws have been reported to be quite fragile so be gentle with them! @@ -63,5 +67,5 @@ pacman -S mingw-w64-x86_64-ninja --noconfirm ## InvalidException: Device unsupported cmd -You need to update the firmware of you Chameleon. +You need to update the firmware of your Chameleon. From 476775a701e673689e26658fcfbb4d519bf2457f Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Tue, 5 Sep 2023 10:51:02 +0300 Subject: [PATCH 21/25] Update troubleshooting.md reminding people to turn on location setting in android --- docs/troubleshooting.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 047ee40..de377f2 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -11,6 +11,12 @@ It has reported that on some devices the electric connection is not good, some g You can try to dismantle very gently the screws and PCB, clean them and put them back in place. Be very careful the screws have been reported to be quite fragile so be gentle with them! +# BLE + +## Difficulties connecting using BLE + +On Android make sure your location is turned, as that allows for scanning of bluetooth devices. + ## Difficulties to use BLE After BLE pairing, both the phone and ChameleonUltra will save a secret key for encrypted communication. If either party deletes the pairing record, it will result in communication failure. If Bluetooth cannot be connected, clearing the pairing information on the other side can solve the problem: From a3cf711cac2d582bef73945f7f3bc276765a8071 Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:26:09 +0300 Subject: [PATCH 22/25] Update modding.md found 1 more project --- docs/modding.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/modding.md b/docs/modding.md index 53195ef..b2c4072 100644 --- a/docs/modding.md +++ b/docs/modding.md @@ -1,3 +1,4 @@ # Third party moddings * [ChameleonUltra Keyring](https://www.printables.com/model/552739-chameleonultra-keyring), an extended frame for ChameleonUltra with a sturdy keyring loop. +* [ChameleonUltra Wristband](https://www.thingiverse.com/thing:6153027), allows the user to wear the ChameleonUltra as a wristband. From ec8da03206369ed373a93205eb9bf66a74a91ca9 Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Tue, 5 Sep 2023 11:52:40 +0300 Subject: [PATCH 23/25] Update README.md fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3ebe76..de6f852 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Read the [available documentation](docs/README.md). # Videos -*Beware some of the instructions might have changed since recording, theck the current documentation in doubt!* +*Beware some of the instructions might have changed since recording, check the current documentation when in doubt!* * [Downloading and compiling the official CLI](https://www.youtube.com/watch?v=VGpAeitNXH0) * [Downloading ChameleonUltraGUI](https://www.youtube.com/watch?v=rHH7iqbX3nY) From 7fe61d995b2dc3c7187acb217b5754a177372a5e Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:09:33 +0300 Subject: [PATCH 24/25] Update README.md groupped documentation to be more readable --- docs/README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/README.md b/docs/README.md index 18ff5b3..61e5aa6 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,24 +4,32 @@ This guide goal is to guide you through setting up and using your Chameleon Ultr This Guide is split up into multiple "subguides": +### About the device + - [Whitepaper](./technical_whitepaper.md): Discover what the Chameleon Ultra is capable of - [Hardware](./hardware.md): Learn to know the hardware of your Chameleon - [Firmware](./firmware.md): Your Chameleon runs a firmware, learn what it can do and how to use it +### Interacting with the device + +- [Quickstart](./quickstart.md): for the impatient people to just get you up and running with anything. + - [CLI](./cli.md): The official way to control your Chameleon is via the **C**ommand **L**ine **I**nterface (CLI) . Learn how to install and master the CLI. - [GUIs](./gui.md): Some people also develop **G**raphical **U**ser **I**nterfaces (GUIs), these may be a good start for people that do not want to deal with a CLI. - [Troubleshooting](./troubleshooting.md): For when things go wrong, here are some common tips to maybe fix whatever issue you might have. -- [FAQ](./faq.md): Frequently Asked Questions, if you have a question, it might already be answered here. - -- [Quickstart](./quickstart.md): for the impatient people to just get you up and running with anything. +### For developers - [Development](./development.md): for all developers. This covers how to build firmware from source and set up a development environment. - [Protocol](./protocol.md): the gory details of the communication protocol, useful if you want to develop your own client. +### Miscellaneous + - [Modding](./modding.md): third party moddings worth mentioning. + +- [FAQ](./faq.md): Frequently Asked Questions, if you have a question, it might already be answered here. From ea67c5cec533203132e32241a6a8e16fd995da81 Mon Sep 17 00:00:00 2001 From: mitmarcus <114725463+mitmarcus@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:21:48 +0300 Subject: [PATCH 25/25] Update README.md --- docs/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/README.md b/docs/README.md index 61e5aa6..25921f4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,17 +6,17 @@ This Guide is split up into multiple "subguides": ### About the device -- [Whitepaper](./technical_whitepaper.md): Discover what the Chameleon Ultra is capable of +- [Whitepaper](./technical_whitepaper.md): Discover what the Chameleon Ultra is capable of. -- [Hardware](./hardware.md): Learn to know the hardware of your Chameleon +- [Hardware](./hardware.md): Learn to know the hardware of your Chameleon. -- [Firmware](./firmware.md): Your Chameleon runs a firmware, learn what it can do and how to use it +- [Firmware](./firmware.md): Your Chameleon runs a firmware, learn what it can do and how to use it. ### Interacting with the device -- [Quickstart](./quickstart.md): for the impatient people to just get you up and running with anything. +- [Quickstart](./quickstart.md): For the impatient people to just get you up and running with anything. -- [CLI](./cli.md): The official way to control your Chameleon is via the **C**ommand **L**ine **I**nterface (CLI) . Learn how to install and master the CLI. +- [CLI](./cli.md): The official way to control your Chameleon is via the **C**ommand **L**ine **I**nterface (CLI). Learn how to install and master the CLI. - [GUIs](./gui.md): Some people also develop **G**raphical **U**ser **I**nterfaces (GUIs), these may be a good start for people that do not want to deal with a CLI. @@ -24,12 +24,12 @@ This Guide is split up into multiple "subguides": ### For developers -- [Development](./development.md): for all developers. This covers how to build firmware from source and set up a development environment. +- [Development](./development.md): For all developers. This covers how to build firmware from source and set up a development environment. -- [Protocol](./protocol.md): the gory details of the communication protocol, useful if you want to develop your own client. +- [Protocol](./protocol.md): The gory details of the communication protocol, useful if you want to develop your own client. ### Miscellaneous -- [Modding](./modding.md): third party moddings worth mentioning. +- [Modding](./modding.md): Third party moddings worth mentioning. -- [FAQ](./faq.md): Frequently Asked Questions, if you have a question, it might already be answered here. +- [FAQ](./faq.md): **F**requently **A**sked **Q**uestions, if you have a question, it might already be answered here.