Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Puzzle FW #67

Merged
merged 8 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ jobs:
echo "slug=${slug}" >> "${GITHUB_ENV}"

- name: Build and test
env: # Or as an environment variable
HIDDEN_MESSAGE: ${{ secrets.HIDDEN_MESSAGE }}
run: |
./build.sh "./rust-exercises-${{ env.slug }}"

Expand Down
14 changes: 14 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pushd boards/dk-solution
cargo build --target=thumbv7em-none-eabihf
cargo fmt --check
popd
pushd boards/dongle
cargo build --target=thumbv7em-none-eabihf
cargo fmt --check
popd
pushd radio-app
cargo build --target=thumbv7em-none-eabihf --release
cargo fmt --check
Expand All @@ -49,6 +53,14 @@ pushd consts
cargo build
cargo fmt --check
popd
pushd puzzle-fw
cargo build --target=thumbv7em-none-eabihf --release
cargo fmt --check
popd
pushd loopback-fw
cargo build --target=thumbv7em-none-eabihf --release
cargo fmt --check
popd
popd

# Only build the templates (they will panic at run-time due to the use of todo!)
Expand Down Expand Up @@ -78,5 +90,7 @@ cp -r ./exercise-solutions "${OUTPUT_NAME}/"
cp -r ./nrf52-code "${OUTPUT_NAME}/"
cp -r ./xtask "${OUTPUT_NAME}/"
cp -r ./.cargo "${OUTPUT_NAME}/"
cp ./nrf52-code/puzzle-fw/target/thumbv7em-none-eabihf/release/puzzle-fw "${OUTPUT_NAME}/nrf52-code/boards/dongle-fw/puzzle-fw"
cp ./nrf52-code/loopback-fw/target/thumbv7em-none-eabihf/release/loopback-fw "${OUTPUT_NAME}/nrf52-code/boards/dongle-fw/loopback-fw"
find "${OUTPUT_NAME}" -name target -type d -print0 | xargs -0 rm -rf
zip -r "${OUTPUT_NAME}.zip" "${OUTPUT_NAME}"
8 changes: 4 additions & 4 deletions exercise-book/src/nrf52-radio-dongle.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ After the device has been programmed it will automatically reset and start runni
```console
$ cargo xtask usb-list
(..)
Bus 001 Device 020: ID 1209:0309 <- nRF52840 Dongle (loopback.hex)
Bus 001 Device 020: ID 1209:0309 <- nRF52840 Dongle (loopback-fw)
```

The `loopback` app will log messages over the USB interface. To display these messages on the host we have provided a cross-platform tool: `cargo xtask serial-term`.
Expand All @@ -69,7 +69,7 @@ The `loopback` app will log messages over the USB interface. To display these me

```console
$ cargo xtask serial-term
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm app=loopback.hex
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm app=loopback-fw
```

This line is printed by the `loopback` app on boot. It contains the device ID of the dongle, a 64-bit unique identifier (so everyone will see a different number); the radio channel that the device will use to communicate; and the transmission power of the radio in dBm.
Expand All @@ -86,7 +86,7 @@ At this point you should *not* get more output from `cargo xtask serial-term`.

```console
$ cargo xtask serial-term
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm app=loopback-fw
received 7 bytes (CRC=Ok(0x2459), LQI=0)
received 5 bytes (CRC=Ok(0xdad9), LQI=0)
received 6 bytes (CRC=Ok(0x72bb), LQI=0)
Expand All @@ -102,7 +102,7 @@ requested channel change to channel 11
Then you should see new output from `cargo xtask serial-term`:

```console
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm app=loopback-fw
(..)
now listening on channel 11
```
Expand Down
2 changes: 1 addition & 1 deletion exercise-book/src/nrf52-radio-puzzle-help.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Something you will likely run into while solving this exercise are *character* l

*IMPORTANT* you do not need to use the `str` or `char` API to solve this problem, other than for printing purposes. Work directly with slices of bytes (`[u8]`) and bytes (`u8`); and only convert those to `str` or `char` when you are about to print them.

> Note: The plaintext string is *not* stored in `puzzle.hex` so running `strings` on it will not give you the answer. Nice try.
> Note: The plaintext string is *not* stored in `puzzle-fw` so running `strings` on it will not give you the answer. Nice try.

## Make sure not to flood the log buffer

Expand Down
4 changes: 2 additions & 2 deletions exercise-book/src/nrf52-radio-puzzle.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ Your task in this section is to decrypt the [substitution cipher] encrypted *ASC
[substitution cipher]: https://en.wikipedia.org/wiki/Substitution_cipher
[`heapless`]: https://docs.rs/heapless

✅ Flash the `puzzle.hex` program on the Dongle. Follow the instructions from the "nRF52840 Dongle" section but flash the `puzzle.hex` program instead of the `loopback.hex` one -- don't forget to put the Dongle in bootloader mode before invoking `nrfdfu`.
✅ Flash the `puzzle-fw` program on the Dongle. Follow the instructions from the "nRF52840 Dongle" section but flash the `puzzle-fw` program instead of the `loopback-fw` one -- don't forget to put the Dongle in bootloader mode before invoking `nrfdfu`.

> Note: If you experienced USB issues with `loopback.hex` you can use the `puzzle-nousb*.hex` variants.
> Note: If you experienced USB issues with `loopback-fw` you can use the older `puzzle-nousb*.hex` variants.

Like in the previous sections the Dongle will listen for radio packets -- this time over *channel 25* -- while also logging messages over a USB/serial interface.

Expand Down
2 changes: 1 addition & 1 deletion exercise-book/src/nrf52-radio-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

```console
$ cargo xtask serial-term
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm app=loopback.hex
deviceid=588c06af0877c8f2 channel=20 TxPower=+8dBm app=loopback-fw
received 5 bytes (CRC=Ok(0xdad9), LQI=53)
```

Expand Down
27 changes: 27 additions & 0 deletions nrf52-code/boards/dongle-fw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# nRF52840 USB Dongle Firmware

This folder is empty on Github, but in a release .zip archive it will contain:

* Puzzle Firmware - see <../../puzzle-fw>
* Loopback Firmware - see <../../loopback-fw>

## Loading Firmware

You can load one firmware image at a time into your USB dongle. Load the
firmware image with `nrfdfu`:

```console
$ cargo install nrfdfu
$ # Now press the dongle's 'Reset' button - the red LED should come on...
$ nrfdfu ./nrf52-code/boards/dongle-fw/puzzle-fw
[INFO nrfdfu] Sending init packet...
[INFO nrfdfu] Sending firmware image of size 37568...
[INFO nrfdfu] Done.
```

## Compiling Firmware

Enter the source directory for the firmware, and run `cargo build --release`.
Note that if you compile your own puzzle firmware, you won't have the same
secret message as everyone else because it's not in the source code anywhere
(it's a Github Secret).
131 changes: 131 additions & 0 deletions nrf52-code/boards/dongle-fw/old/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# `dongle`

Pre-made applications for the nRF52840 Dongle.

These applications will be used in the radio workshop.

## Hardware

### LEDs

- The green LED (LD1) is connected to pin P0.6
- The red channel of the RGB LED (LD2) is connected to pin P0.8
- The green channel of the RGB LED (LD2) is connected to pin P**1**.9
- The blue channel of the RGB LED (LD2) is connected to pin P0.12

Both LEDs are mounted near the USB connector.

### Buttons

- The Reset button is mounted sideways near the edge of the board that's opposite of the USB connector.
- The SW1 button is connected to pin P**1**.06. This round-ish button is right next to the RESET button but closer to the USB connector.

## Changing the puzzle secret string

### Create the secret string

Run the `puzzlegen.rs` program on the host to create a new secret string.

```console
cargo new --bin puzzlegen
cp puzzlegen.rs puzzlegen/src/main.rs
cd puzzlegen
# or manually modify the Cargo.toml
cargo add rand
# update the plaintext in `src/main.rs`
cargo run
```

Take note of the output; it will look like this:

```text
from: [116, 68, 123, 97, 47, 46, 90, 120, 34, 49, 59, 39, 50, 106, 71, 75, 108, 115, 81, 117, 69, 57, 76, 41, 100, 38, 93, 58, 78, 126, 70, 56, 84, 111, 113, 91, 89, 55, 40, 114, 122, 52, 61, 64, 45, 79, 67, 83, 48, 66, 63, 104, 43, 77, 44, 54, 98, 92, 94, 60, 62, 118, 87, 80, 95, 74, 65, 112, 109, 73, 110, 101, 53, 86, 33, 121, 42, 35, 85, 82, 105, 36, 37, 119, 125, 51, 96, 99, 88, 32, 103, 72, 107, 124, 102]
to: [81, 78, 109, 61, 120, 87, 125, 98, 100, 91, 97, 66, 57, 117, 49, 64, 48, 85, 75, 73, 92, 101, 83, 110, 62, 89, 35, 37, 93, 71, 123, 121, 60, 38, 115, 102, 59, 47, 108, 80, 58, 44, 86, 111, 41, 84, 96, 50, 51, 70, 43, 112, 79, 46, 113, 107, 106, 116, 65, 68, 69, 77, 105, 56, 103, 67, 40, 54, 99, 55, 45, 63, 34, 88, 119, 74, 94, 32, 114, 36, 95, 124, 118, 76, 126, 72, 82, 122, 33, 104, 90, 39, 42, 52, 53]
secret: "<p=-*Uh5&Ph6=PQ_z_6=Q_-Zh_-h&IPh?cj?>>?>h$IUQhL&P*Up&6w"
```

### Generate `puzzle` ELF

```console
git clone --branch dongle-puzzle https://github.com/japaric/embedded2020
cd embedded2020/firmware/apps
```

Find `puzzle.rs` in the `embedded2020/firmware/apps/src/bin` folder.

Update `puzzle.rs` with the `FROM`, `TO` and `SECRET` data that you got from `puzzlegen`

````rust
static FROM: &[u8] = &[
116, 68, 123, 97, 47, 46, 90, 120, 34, 49, 59, 39, 50, 106, 71, 75, 108, 115, 81, 117, 69, 57,
76, 41, 100, 38, 93, 58, 78, 126, 70, 56, 84, 111, 113, 91, 89, 55, 40, 114, 122, 52, 61, 64,
45, 79, 67, 83, 48, 66, 63, 104, 43, 77, 44, 54, 98, 92, 94, 60, 62, 118, 87, 80, 95, 74, 65,
112, 109, 73, 110, 101, 53, 86, 33, 121, 42, 35, 85, 82, 105, 36, 37, 119, 125, 51, 96, 99, 88,
32, 103, 72, 107, 124, 102,
];

static TO: &[u8] = &[
81, 78, 109, 61, 120, 87, 125, 98, 100, 91, 97, 66, 57, 117, 49, 64, 48, 85, 75, 73, 92, 101,
83, 110, 62, 89, 35, 37, 93, 71, 123, 121, 60, 38, 115, 102, 59, 47, 108, 80, 58, 44, 86, 111,
41, 84, 96, 50, 51, 70, 43, 112, 79, 46, 113, 107, 106, 116, 65, 68, 69, 77, 105, 56, 103, 67,
40, 54, 99, 55, 45, 63, 34, 88, 119, 74, 94, 32, 114, 36, 95, 124, 118, 76, 126, 72, 82, 122,
33, 104, 90, 39, 42, 52, 53,
];

// store the secret rather than the plaintext -- otherwise `strings $elf` will reveal the answer
static SECRET: &[u8] = b"<p=-*Uh5&Ph6=PQ_z_6=Q_-Zh_-h&IPh?cj?>>?>h$IUQhL&P*Up&6w";
````

Build the program; this will produce an ELF file called `puzzle` (no file ending).

```console
cargo build --bin puzzle --release
```

Copy this ELF file from `embedded2020/firmware/target/thumbv7em-none-eabi/release` to `embedded-trainings-2020/boards/dongle`

Test the produced `puzzle` file:

- flash it onto a dongle using `nrfdfu puzzle`. The green LED on the dongle should turn on
- run `cargo xtask serial-term`; you should see the following output. `deviceid` will be different

```text
deviceid=d90eedf1978d5fd2 channel=25 TxPower=+8dBm app=puzzle
```

- run the `radio-puzzle-solution` program on a DK; it should be able to decrypt the new secret
- run `cargo xtask change-channel <some number between 11 and 26>` to test changing the Dongle's radio channel
- modify and re-run the `radio-puzzle-solution` program on a DK to solve the puzzle using a the channel you set in the previous step

### Generate `puzzle-nousb-*`

The procedure is similar to the one for generating the `puzzle` ELF file. The differences are:

- you build `puzzle-nousb.rs` in the `embedded2020` repository and copy `embedded2020/firmware/target/thumbv7em-none-eabi/release/puzzle-nousb` over
- you also need to change `const CHANNEL` in `puzzle-nousb.rs`
- you need to produce one ELF file per hard-coded radio channel.

Also test these `nousb` ELF files. Note that the green LED won't turn on when the dongle restarts! The green LED will toggle when a new packet is received and the blue LED will turn on when the decoded secret is received. Also, `cargo xtask change-channel` won't work with the `nousb` variants so you can skip that test.

## Addendum

In October 2023, Jonathan changed the USB Vendor ID from 0x2020 to the 0x1209 suggested by https://pid.codes. Rather than find the old
firmware source code and recompile it, it was easier to patch the binaries.

```console
$ diff <(hexdump -C puzzle) <(hexdump -C puzzle-1209)
2363c2363
< 000131b0 00 00 02 12 01 00 02 ef 02 01 40 20 20 09 03 00 |..........@ ...|
---
> 000131b0 00 00 02 12 01 00 02 ef 02 01 40 09 12 09 03 00 |..........@.....|
$ diff <(hexdump -C loopback) <(hexdump -C loopback-1209)
2344c2344
< 000131b0 00 00 02 12 01 00 02 ef 02 01 40 20 20 09 03 00 |..........@ ...|
---
> 000131b0 00 00 02 12 01 00 02 ef 02 01 40 09 12 09 03 00 |..........@.....|
$
```

## References

- [nRF52840 Dongle section on Nordic Semiconductor's info center](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fug_getting_started%2FUG%2Fgs%2Fdevelop_sw.html&cp=1_0_2)
11 changes: 11 additions & 0 deletions nrf52-code/boards/dongle-fw/old/memory.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
MEMORY
{
/* Bootloader is split in 2 parts: the first part lives in the range
0..0x1000; the second part lives at the end of the 1 MB Flash. The range
selected here collides with neither */
FLASH : ORIGIN = 0x1000, LENGTH = 0x7f000

/* The bootloader uses the first 8 bytes of RAM to preserve state so don't
touch them */
RAM : ORIGIN = 0x20000008, LENGTH = 0x3fff8
}
File renamed without changes.
1 change: 1 addition & 0 deletions nrf52-code/boards/dongle/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
18 changes: 18 additions & 0 deletions nrf52-code/boards/dongle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
authors = ["Ferrous Systems"]
edition = "2018"
license = "MIT OR Apache-2.0"
name = "dongle"
version = "0.0.0"

[dependencies]
cortex-m = {version = "0.7.6", features = ["critical-section-single-core"]}
cortex-m-rt = "0.7.2"
cortex-m-semihosting = "0.5.0"
critical-section = "1.1.2"
defmt = "0.3.5"
defmt-rtt = "0.4"
embedded-hal = "0.2.7"
hal = { package = "nrf52840-hal", version = "0.16.0" }
heapless = "0.8.0"
panic-probe = { version = "0.3.0", features = ["print-defmt"] }
Loading