+## 🏗️ How It's Organized
-1. **Key Generation:** Both the host and the token generate a new, persistent ECDSA keypair.
-2. **Public Key Exchange:** The host and token exchange their public keys.
-3. **Golden Hash:** The host generates a "golden hash" of its boot file and shares it with the token. This hash represents the known-good state of the host's software.
+```
+FreeRTOS Tasks (The Chaos):
+├── Serial (Priority 26) - Your USB connection
+├── Watchdog (Priority 27) - Judges everything
+├── WiFi Background (Priority 25) - Talks to WiFi chip
+├── HTTP Server (Priority 5) - Handles web requests
+└── WiFi Init (Priority 5) - Starts the AP, then dips
+```
-### Phase 2: Mutual Attestation & Secure Channel Establishment
+Each task does its thing. Sometimes they play nice. Sometimes they don't.
-This phase is performed on every boot to establish a secure session.
+## � The Problems (Why You're Here)
-
+### Problem #1: Serial Breaks When WiFi Starts
+- **What happens:** You plug it in, start provisioning, then enable WiFi → EVERYTHING BREAKS
+- **Why:** WiFi initialization steals CPU time from serial task
+- **Current fix:** Wait 60 seconds before enabling WiFi so provisioning can finish
+- **Better fix:** TODO (we're working on it)
-1. **Ephemeral Key Generation:** The host and token each generate an ephemeral ECDH keypair.
-2. **Signed Key Exchange:** They exchange their ephemeral public keys, signing them with their persistent private keys from the pairing phase.
-3. **Signature Verification:** Each party verifies the signature on the received ephemeral public key using the other's stored persistent public key.
-4. **Secure Secret Derivation:** A shared secret is derived using the ECDH algorithm.
-5. **Session Key Generation:** A KDF (Key Derivation Function) is used to generate an AES-128 session key from the shared secret.
-6. **Channel Verification:** The channel is verified with an encrypted ping-pong exchange.
+**TL;DR:** Do provisioning FIRST, THEN WiFi is okay.
-### Phase 3: Integrity Verification & Runtime Guard
+### Problem #1.5: Garbage Output During Provisioning (The Real Issue)
+- **What you see:** Corrupted binary data mixed with partial debug messages
+- **Example:**
+```
+�YVOS����fCOO�f=p$
+*Sent T2H_ECDH_SHARE (host-initiated ECDH)
+J��y�����)ۘ%�EU
+```
+- **Why it happens:** Serial ISR receiving data while main protocol handler is processing
+- **Root cause:** No proper frame synchronization - data gets interleaved
+- **This means:** Protocol state machine is running during USB ISR, causing data corruption
+- **Impact:** ECDH exchange fails, provisioning breaks completely
-This phase ensures the host is running the correct software before allowing it to boot.
+**TL;DR:** Serial + WiFi task switching breaks the protocol. Need to disable WiFi polling DURING provisioning.
-
+### Problem #2: macOS Hates Unplugging It
+- **What happens:** Unplug/replug a few times → macOS loses the device completely
+- **Why:** macOS USB driver gets confused (not our problem but we suffer)
+- **How to fix it:** Restart your Mac (bruh)
+- **Pro tip:** Just leave it plugged in. Works fine if you don't touch it.
-1. **Integrity Challenge:** The token sends a random nonce to the host.
-2. **Hash Calculation:** The host calculates a hash of its current boot file.
-3. **Signed Response:** The host signs the hash and the nonce with its persistent private key and sends the signature and hash to the token.
-4. **Verification:** The token verifies the signature and compares the received hash with the stored "golden hash".
-5. **Boot Signal:** If the verification is successful, the token sends a `T2H_BOOT_OK` signal to the host; otherwise, it sends `T2H_INTEGRITY_FAIL_HALT`.
+**TL;DR:** Regular Pico 2 doesn't have this. WiFi chip adds drama.
-### Runtime Heartbeat
+### Problem #3: API Info Crashes
+- **What it tried to do:** Read temperature sensor
+- **What actually happened:** Pico went to another dimension 🌀
+- **Status:** Removed from API
+- **Can we bring it back?** Maybe, if we rewrite it
-After a successful boot, the host sends periodic heartbeat messages to the token to maintain the session.
+**TL;DR:** Just don't ask for it.
-### Shutdown Policy
+## 🔨 Build It
-The system will shut down under the following conditions:
+```bash
+cd build
+cmake ..
+make -j4
+picotool load pico_project_template.uf2 -u -f
+```
-* A protocol phase is not completed within 30 seconds.
-* Either the host or token sends a "no-go" signal.
-* The `T2H_BOOT_OK` signal is not received within 2 minutes of starting the attestation process.
-* The heartbeat timeout occurs more than 3 times.
+Standard procedure. Nothing fancy.
-## Building and Running the Project
+## 🧪 Test It
-### Prerequisites
+### Test via USB Serial
+```bash
+screen /dev/tty.usbmodem* 115200
+# See debug output, watch provisioning happen
+```
-* Raspberry Pi Pico SDK
-* CMake (version 3.13 or later)
-* ARM GCC Compiler
+### Test via WiFi
+Connect to `MASTR-Token` WiFi, then:
-### Build Instructions
+```bash
+# Quick check - is it alive?
+curl http://192.168.4.1/api/ping
-1. **Create a build directory:**
+# Check provisioning status
+curl http://192.168.4.1/api/status
- ```bash
- mkdir build
- cd build
- ```
+# Open web interface
+open http://192.168.4.1
+```
-2. **Configure for your board:**
+## � Stats
- * **For Raspberry Pi Pico (RP2040):**
+- **Firmware Size:** 463 KB (still fits in 4 MB)
+- **RAM Used:** 138 KB (we got room)
+- **Bugs:** Still has some but we shipped it anyway
- ```bash
- cmake .. -DPICO_BOARD=pico
- ```
+## 🎯 What's Next
- * **For Raspberry Pi Pico W (RP2040 with WiFi):**
+1. **FIX: Disable WiFi polling during provisioning**
+ - Add `provisioning_active` flag to protocol_state
+ - Set to `true` at boot, `false` when reaching state 0x40
+ - Modify `wifi_background_task()` to skip `cyw43_arch_poll()` if provisioning_active
+ - This prevents task switching during ECDH key exchange
- ```bash
- cmake .. -DPICO_BOARD=picow
- ```
+2. **Test full flow:** Provision → then WiFi polling starts → both work together
- * **For a generic RP2350 board:**
+3. **Maybe fix `/api/info`** → Temperature reading without crashing
- ```bash
- cmake .. -DPICO_PLATFORM=rp2350
- ```
+4. **macOS USB drama** → Not much we can do, macOS issue
-3. **Build the project:**
+---
- ```bash
- make
- ```
-
-### Running
-
-1. Connect your Pico board to your computer while holding the `BOOTSEL` button.
-2. Drag and drop the `mastr.uf2` file from the `build` directory onto the `RPI-RP2` mass storage device.
-
-## Testing
-
-The project uses the Unity test framework. The tests are located in the `test` directory.
-
-### Running the Tests
-
-1. Navigate to the build directory: `cd build`
-2. Build the test runner: `make test_runner`
-3. Run the tests: `ctest`
+Made on a Pico 2 W. Works most of the time. That's a win in my book. ✌️
\ No newline at end of file
diff --git a/src/main.c b/src/main.c
index a67d82c..786c295 100644
--- a/src/main.c
+++ b/src/main.c
@@ -10,11 +10,12 @@
#include "constants.h"
#include "protocol.h"
#include "crypt.h"
+#include "net/wifi_ap.h"
// Add binary info
bi_decl(bi_program_name("MASTR"));
bi_decl(bi_program_description("Mutual Attested Secure Token for Robotics"));
-bi_decl(bi_program_version_string("0.0.2"));
+bi_decl(bi_program_version_string("0.0.3"));
void print_board_info() {
// All debug output goes through DEBUG_MSG protocol
@@ -151,6 +152,38 @@ int main() {
// TODO check if the token has been provisioned, if not, do special magic to
// start the web server in a special admin mode.
+ // WiFi initialization with LONG delay
+ // IMPORTANT: WiFi initialization is causing serial provisioning issues
+ // We start WiFi but NOT the background polling task
+ if (!wifi_ap_init()) {
+ print_dbg("WARNING: WiFi subsystem preparation failed\n");
+ } else {
+ // NOTE: WiFi background task DISABLED - it interferes with serial
+ // The HTTP server will still work, but may not handle incoming packets
+ // as quickly without the background polling task
+ /*
+ xTaskCreate(
+ wifi_background_task,
+ "WiFi-BG",
+ DEFAULT_STACK_SIZE,
+ NULL,
+ configMAX_PRIORITIES - 7, // Priority 25
+ NULL
+ );
+ */
+
+ // Create WiFi AP initialization task (priority 5: low priority)
+ // Waits 60 seconds to let scheduler stabilize and provisioning complete
+ xTaskCreate(
+ wifi_ap_init_task,
+ "WiFi-Init",
+ DEFAULT_STACK_SIZE,
+ NULL,
+ configMAX_PRIORITIES - 27, // Priority 5
+ NULL
+ );
+ }
+
// Start the FreeRTOS scheduler
vTaskStartScheduler();
diff --git a/src/net/ap/ap_manager.c b/src/net/ap/ap_manager.c
new file mode 100644
index 0000000..cc7e654
--- /dev/null
+++ b/src/net/ap/ap_manager.c
@@ -0,0 +1,72 @@
+#include "ap_manager.h"
+
+#include "pico/stdlib.h"
+#include "pico/cyw43_arch.h"
+#include Mutual Attested Secure Token for Robotics
+ +