Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
453
FIELD_STRENGTH_REPORTING_RESEARCH.md
Normal file
453
FIELD_STRENGTH_REPORTING_RESEARCH.md
Normal file
@@ -0,0 +1,453 @@
|
||||
# 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*
|
||||
Reference in New Issue
Block a user