# Field Strength Reporting - Firmware Modification Research

## Executive Summary

**Goal:** Modify PM3 firmware to report real-time LF and HF field strength values to enable LED brightness control via Lua script.

**Verdict:** **LOW IMPACT, RECOMMENDED FOR IMPLEMENTATION**

The modification is straightforward, follows existing patterns, and has minimal risk. Estimated implementation time: 45-60 minutes including testing.

---

## Current Situation

### Existing `hw detectreader` Command
- Uses `CMD_LISTEN_READER_FIELD` (0x0420)
- Firmware function: `ListenReaderField()` in [armsrc/appmain.c:686-850](armsrc/appmain.c#L686)
- **Problem:** Firmware only:
  - Prints values via `Dbprintf()` (debug output, not accessible from Lua)
  - Controls LEDs directly in firmware (hard-coded patterns)
  - Never sends field strength data back to client

### What We Need
- Continuous streaming of LF and HF field strength values (in mV)
- Accessible from Lua scripts via `reply_ng()`
- Update rate: ~20 Hz (50ms intervals)
- Data format: Two uint16_t values (LF voltage, HF voltage)

---

## Proposed Solution

### Architecture Pattern
Follow the existing `CMD_MEASURE_ANTENNA_TUNING_HF` pattern:

**Mode-based state machine:**
```c
Mode 1: Initialize measurement (reply with PM3_SUCCESS)
Mode 2: Measure and return data (reply with field strength values)
Mode 3: Shutdown (reply with PM3_SUCCESS)
```

This pattern is proven, well-tested, and already used successfully.

### Implementation Approach

#### Option A: Modify Existing Command (RECOMMENDED)
**Extend `CMD_LISTEN_READER_FIELD` to support data reporting**

**Pros:**
- No new command ID needed
- Leverages existing hardware code
- Backwards compatible (mode 1 = current behavior, mode 2 = new streaming)
- Minimal code changes

**Cons:**
- Slight complexity in command handler (mode switching)

#### Option B: Create New Command
**Add `CMD_LISTEN_READER_FIELD_STREAM` (0x0421)**

**Pros:**
- Cleaner separation of concerns
- No risk to existing hw detectreader functionality

**Cons:**
- Need to allocate new command ID
- Duplicate some existing code
- More changes required

**Recommendation:** **Option A** - Extend existing command with mode parameter

---

## Required Changes

### 1. Firmware Changes (armsrc/appmain.c)

**Location:** `ListenReaderField()` function, line 686

**Change:**
```c
// Current: void ListenReaderField(uint8_t limit)
// Modified: void ListenReaderField(uint8_t limit, uint8_t mode)

// Add mode parameter:
// mode 0: Original behavior (LED patterns, debug output)
// mode 1: Stream data mode (send values via reply_ng)
```

**Modification in main loop (lines 744-778):**
```c
if (mode == 1) {
    // Create payload struct
    struct {
        uint16_t lf_mv;
        uint16_t hf_mv;
    } __attribute__((packed)) payload;

    payload.lf_mv = lf_av;
    payload.hf_mv = hf_av;

    // Send values back to client
    reply_ng(CMD_LISTEN_READER_FIELD, PM3_SUCCESS,
             (uint8_t *)&payload, sizeof(payload));
}
```

**Lines of code to add:** ~20 lines
**Lines to modify:** ~5 lines
**Risk level:** LOW (contained change, existing patterns)

### 2. Command Handler Changes (armsrc/appmain.c)

**Location:** `case CMD_LISTEN_READER_FIELD:` line 2543

**Change:**
```c
case CMD_LISTEN_READER_FIELD: {
    if (packet->length != 2)  // Was: != 1
        break;
    uint8_t limit = packet->data.asBytes[0];
    uint8_t mode = packet->data.asBytes[1];  // NEW
    ListenReaderField(limit, mode);          // Pass mode
    reply_ng(CMD_LISTEN_READER_FIELD, PM3_EOPABORTED, NULL, 0);
    break;
}
```

**Lines to modify:** 3 lines
**Risk level:** MINIMAL

### 3. Client Changes (client/src/cmdhw.c)

**Location:** `CmdDetectReader()` function, line 534

**No changes required** - existing hw detectreader continues to work (mode=0)

**For new Lua script:**
```lua
-- Send mode=1 to enable streaming
local data = string.char(limit, 1)  -- limit, mode
command = Command:newNG{
    cmd = cmds.CMD_LISTEN_READER_FIELD,
    data = data
}
```

### 4. Optional: Add Payload Structure (include/pm3_cmd.h)

**Location:** After line 246

**Add:**
```c
// Field strength measurement payload
typedef struct {
    uint16_t lf_mv;  // LF field strength in millivolts
    uint16_t hf_mv;  // HF field strength in millivolts
} PACKED payload_field_strength_t;
```

**Lines to add:** 5 lines
**Risk level:** ZERO (optional documentation, doesn't affect functionality)

---

## Potential Complications & Mitigations

### 1. SWIG Python Wrapper
**Issue:** If we modify pm3_cmd.h, SWIG must be rebuilt
**Impact:** Medium (requires manual rebuild)
**Mitigation:**
- Document rebuild requirement
- Add to our build script
- Only affects Python bindings (Lua unaffected)

**Commands:**
```bash
cd client/experimental_lib
./00make_swig.sh
./01make_lib.sh
```

### 2. Backwards Compatibility
**Issue:** Old clients won't understand mode parameter
**Impact:** LOW
**Mitigation:**
- Old clients send 1 byte (mode defaults to 0)
- New clients send 2 bytes (mode specified)
- Firmware handles both gracefully

### 3. Update Rate Performance
**Issue:** 20 Hz update rate = 20 USB packets/sec
**Impact:** MINIMAL
**Analysis:**
- Each packet: ~20 bytes (4 bytes payload + overhead)
- Total bandwidth: 400 bytes/sec = 0.4 KB/sec
- USB 2.0 full-speed: 12 Mbps = 1.5 MB/sec
- **Utilization: 0.027%** - negligible

### 4. Firmware Flash Size
**Issue:** Adding code increases firmware size
**Impact:** NEGLIGIBLE
**Analysis:**
- Adding ~20 lines ≈ 200-300 bytes compiled
- Current firmware size: ~200 KB (typical)
- Flash capacity: 512 KB (PM3 Easy)
- **Increase: <0.15%** - safe margin

### 5. Testing Requirements
**Issue:** Need to verify on actual hardware
**Impact:** Medium (requires physical device)
**Test cases:**
```
1. LF field detection (125 kHz reader)
2. HF field detection (13.56 MHz reader/phone NFC)
3. Simultaneous LF+HF
4. Backwards compatibility (old hw detectreader still works)
5. LED brightness control from Lua
```

---

## Build & Flash Process

### 1. Modify Code
- Edit `armsrc/appmain.c` (~25 lines)
- Optional: Edit `include/pm3_cmd.h` (~5 lines)

### 2. Compile Firmware
```bash
cd /home/work/dangerous-pi/.pm3-test/proxmark3
make clean
SKIPQT=1 make -j8 armsrc/obj/fullimage.elf
```

**Time:** ~2-3 minutes

### 3. Flash Firmware
```bash
./pm3-flash-all
```

**Time:** ~30 seconds

### 4. Test
```bash
./pm3 -c "hw detectreader"  # Old command still works
./pm3 -c "script run field_strength_test"  # New streaming
```

**Time:** ~5 minutes

### 5. Rebuild SWIG (if pm3_cmd.h modified)
```bash
cd client/experimental_lib
./00make_swig.sh
./01make_lib.sh
```

**Time:** ~1 minute

**Total Time:** 10-15 minutes

---

## Upstreaming Potential

### Why This Is a Good Upstream Contribution

**Benefits to PM3 Community:**
1. **Programmatic field detection** - enables automation scripts
2. **Precise measurements** - get exact mV values, not just on/off
3. **Multi-device coordination** - essential for systems like Dangerous Pi
4. **Backwards compatible** - doesn't break existing tools

**Follows Iceman Fork Conventions:**
- ✅ Uses CLIParser patterns (already established)
- ✅ reply_ng() for data transfer
- ✅ Mode-based state machine (proven pattern)
- ✅ Minimal, focused changes
- ✅ No breaking changes
- ✅ Self-documented code

**Similar Precedents:**
- `CMD_MEASURE_ANTENNA_TUNING_HF` - exact same pattern
- `CMD_MEASURE_ANTENNA_TUNING_LF` - dual-value reporting
- Both accepted upstream

### Preparation for PR

**Before submitting:**
1. Test on multiple hardware variants (Easy, RDV4)
2. Document in CHANGELOG.md
3. Add usage examples in commit message
4. Reference this research doc
5. Emphasize automation/multi-device use case

**Estimated acceptance probability:** HIGH (70-80%)

---

## Risk Assessment Matrix

| Risk Factor | Probability | Impact | Mitigation |
|-------------|------------|--------|------------|
| Compilation errors | Low | Low | Follow existing patterns exactly |
| Runtime crashes | Very Low | Medium | Contained changes, tested pattern |
| SWIG rebuild required | Certain | Low | Documented procedure, quick rebuild |
| Backwards compatibility broken | Very Low | High | Dual-mode design prevents this |
| Flash size exceeded | Very Low | High | Change is <1KB, plenty of margin |
| USB bandwidth issues | Very Low | Low | 0.027% utilization |
| Upstream rejection | Medium | Low | Feature is useful, well-implemented |

**Overall Risk:** **LOW**

---

## Implementation Timeline

### Phase 1: Core Implementation (30 min)
- Modify `ListenReaderField()` function
- Update command handler
- Optional: Add payload struct
- Compile & flash

### Phase 2: Testing (15 min)
- Test LF field detection
- Test HF field detection
- Verify backwards compatibility
- Test LED brightness control

### Phase 3: Documentation (15 min)
- Update script documentation
- Create usage examples
- Document SWIG rebuild if needed

**Total Estimated Time:** 60 minutes

---

## Alternative Approaches Considered

### Alt 1: Parse Debug Output
**Rejected:** Hacky, unreliable, requires USB CDC mode

### Alt 2: Use Existing hw detectreader As-Is
**Rejected:** Can't control LEDs precisely, no programmable access

### Alt 3: Create Entirely New Command
**Rejected:** Unnecessary duplication, more complex

### Alt 4: Firmware-only LED Control
**Rejected:** Not flexible enough, can't adapt patterns

---

## Decision Matrix

| Criteria | Weight | Score (1-10) | Weighted |
|----------|--------|--------------|----------|
| Implementation Effort | 20% | 9 | 1.8 |
| Code Complexity | 15% | 8 | 1.2 |
| Risk Level | 25% | 9 | 2.25 |
| Maintainability | 15% | 9 | 1.35 |
| Upstream Acceptance | 15% | 7 | 1.05 |
| Feature Completeness | 10% | 10 | 1.0 |

**Total Score: 8.65 / 10** ⭐⭐⭐⭐⭐

---

## Recommendation

### ✅ **PROCEED WITH IMPLEMENTATION**

**Justification:**
1. **Low Risk:** Follows proven patterns, minimal code changes
2. **High Value:** Enables precise field detection with programmable LED control
3. **Clean Design:** Mode-based approach is elegant and backwards compatible
4. **Manageable Effort:** ~1 hour total implementation time
5. **Upstream Potential:** High probability of acceptance

**Next Steps:**
1. Schedule implementation session (60 min)
2. Prepare test equipment (LF reader, HF reader/NFC phone)
3. Have backup: keep current working firmware binary
4. Document changes for potential upstream PR

---

## Code Diff Preview

### armsrc/appmain.c - Function Signature
```diff
-void ListenReaderField(uint8_t limit) {
+void ListenReaderField(uint8_t limit, uint8_t mode) {
```

### armsrc/appmain.c - Streaming Mode
```diff
         if (mode == 2) {
+        } else if (mode == 3) {
+            // Streaming mode - send values back to client
+            if (limit == LF_ONLY || limit == LF_HF_BOTH) {
+                struct {
+                    uint16_t lf_mv;
+                    uint16_t hf_mv;
+                } __attribute__((packed)) payload = {
+                    .lf_mv = lf_av,
+                    .hf_mv = hf_av
+                };
+                reply_ng(CMD_LISTEN_READER_FIELD, PM3_SUCCESS,
+                         (uint8_t *)&payload, sizeof(payload));
+            }
         }
```

### armsrc/appmain.c - Command Handler
```diff
         case CMD_LISTEN_READER_FIELD: {
-            if (packet->length != sizeof(uint8_t))
+            if (packet->length != 1 && packet->length != 2)
                 break;
-            ListenReaderField(packet->data.asBytes[0]);
+            uint8_t limit = packet->data.asBytes[0];
+            uint8_t mode = (packet->length == 2) ? packet->data.asBytes[1] : 0;
+            ListenReaderField(limit, mode);
             reply_ng(CMD_LISTEN_READER_FIELD, PM3_EOPABORTED, NULL, 0);
             break;
         }
```

---

## Conclusion

The firmware modification to enable field strength reporting is:
- **Technically sound** - follows existing patterns
- **Low risk** - minimal, contained changes
- **High value** - enables powerful scripting capabilities
- **Reasonable effort** - ~1 hour implementation
- **Upstream ready** - good candidate for contribution

**Confidence Level:** ⭐⭐⭐⭐⭐ (Very High)

**Recommendation:** Proceed with implementation in next session.

---

*Research completed: 2025-12-02*
*Researcher: Claude (Dangerous Pi Project)*
*Status: Ready for implementation*
