Skip to content

fix(vehicle): correct BLE navigation GPS command encoding#54

Merged
Bre77 merged 3 commits into
mainfrom
fm/tfa-ble-pr8-nav-misc
Jul 9, 2026
Merged

fix(vehicle): correct BLE navigation GPS command encoding#54
Bre77 merged 3 commits into
mainfrom
fm/tfa-ble-pr8-nav-misc

Conversation

@Bre77

@Bre77 Bre77 commented Jul 9, 2026

Copy link
Copy Markdown
Member

Intent

PR-8 of the BLE production-readiness program: live-verify the NAV/dashcam/power-mode command group over the real BLE transport. Live-verified all 11 target calls (navigation_request, navigation_gps_request, navigation_sc_request, navigation_waypoints_request, navigation_gps_destination_request, dashcam_save_clip, flash_lights, set_keep_accessory_power_mode on+off, set_low_power_mode on+off) against the test car (VIN LRW3F7EK4NC716336) over m5-btproxy.local, all in a single held BLE connection using the best-effort-wake + poll-confirm strategy from the resolved decisions doc (wake_up() raises a false-negative BluetoothTimeout that must be caught and ignored, confirmed instead by retrying a state read; hold the connection across the whole batch rather than reconnecting per command). These are all ACK-only ('result: True') ACTUATION commands with no BLE state prover - the nav commands set a harmless destination needing no restore, and the two power-mode commands were deliberately toggled True then False in the same session to leave no lasting state change, per the master plan's classification of this group as benign but still real actuation (HOLD-FOR-CAPTAIN). While live-testing, found and fixed a genuine pre-existing bug: navigation_gps_request built its order field as NavigationGpsRequest.RemoteNavTripOrder(order), calling a protobuf nested-enum wrapper (EnumTypeWrapper) as if it were a callable Python IntEnum - it isn't, so the call raised TypeError before any message reached the car. Fixed by passing order=order directly (with a pyright ignore), matching the already-correct sibling navigation_gps_destination_request. Added tests/test_ble_nav_misc_commands.py with mocked-transport regression coverage for all 9 underlying command methods (proving proto construction and ACK-decoding, including a dedicated regression test for the enum bug), and documented both the wake-false-negative pattern and the enum bug as durable project knowledge in AGENTS.md. No production behavior changed except the one-line bug fix; everything else is test-only.

What Changed

  • Fixed BLE signed-command construction for navigation_gps_request by passing the raw protobuf enum value instead of calling the enum wrapper, matching the working GPS destination path.
  • Added mocked BLE transport regression coverage for NAV, dashcam, flash-lights, and power-mode signed commands, including ACK decoding and the navigation GPS enum regression.
  • Updated BLE command documentation with the live-verified command set, best-effort wake guidance, and the navigation GPS enum gotcha.

Risk Assessment

✅ Low: The production change is a narrow one-line protobuf enum construction fix with focused mocked-transport coverage, and I found no material regressions in the surrounding command paths.

Testing

Focused tests passed for all 11 BLE nav/dashcam/power-mode command cases, and the evidence transcript shows each call producing an AES-GCM signed DOMAIN_INFOTAINMENT command with an OK ACK, including navigation_gps_request encoding the raw enum order without the old EnumTypeWrapper call failure.

Evidence: BLE nav/misc decoded command transcript
{
  "commands": [
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        "1 Infinite Loop, Cupertino, CA"
      ],
      "encrypted_with_aes_gcm": true,
      "field": "navigationRequest",
      "method": "navigation_request",
      "payload": {
        "destination": "1 Infinite Loop, Cupertino, CA",
        "order": 0
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 1
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        37.323,
        -122.0322,
        1
      ],
      "encrypted_with_aes_gcm": true,
      "field": "navigationGpsRequest",
      "method": "navigation_gps_request",
      "payload": {
        "lat": 37.323,
        "lon": -122.0322,
        "order": "REMOTE_NAV_TRIP_ORDER_REPLACE"
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 2
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        1
      ],
      "encrypted_with_aes_gcm": true,
      "field": "navigationSuperchargerRequest",
      "method": "navigation_sc_request",
      "payload": {
        "order": 1
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 3
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        "37.3230,-122.0322;37.4419,-122.1430"
      ],
      "encrypted_with_aes_gcm": true,
      "field": "navigationWaypointsRequest",
      "method": "navigation_waypoints_request",
      "payload": {
        "waypoints": "37.3230,-122.0322;37.4419,-122.1430"
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 4
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        37.4419,
        -122.143,
        "Palo Alto, CA",
        1
      ],
      "encrypted_with_aes_gcm": true,
      "field": "navigationGpsDestinationRequest",
      "method": "navigation_gps_destination_request",
      "payload": {
        "destination": "Palo Alto, CA",
        "lat": 37.4419,
        "lon": -122.143,
        "order": "REMOTE_NAV_TRIP_ORDER_REPLACE"
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 5
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [],
      "encrypted_with_aes_gcm": true,
      "field": "dashcamSaveClipAction",
      "method": "dashcam_save_clip",
      "payload": {},
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 6
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [],
      "encrypted_with_aes_gcm": true,
      "field": "vehicleControlFlashLightsAction",
      "method": "flash_lights",
      "payload": {},
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 7
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        true
      ],
      "encrypted_with_aes_gcm": true,
      "field": "setKeepAccessoryPowerModeAction",
      "method": "set_keep_accessory_power_mode",
      "payload": {
        "keep_accessory_power_mode": true
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 8
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        false
      ],
      "encrypted_with_aes_gcm": true,
      "field": "setKeepAccessoryPowerModeAction",
      "method": "set_keep_accessory_power_mode",
      "payload": {
        "keep_accessory_power_mode": false
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 9
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        true
      ],
      "encrypted_with_aes_gcm": true,
      "field": "setLowPowerModeAction",
      "method": "set_low_power_mode",
      "payload": {
        "low_power_mode": true
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 10
    },
    {
      "ack_result": {
        "response": {
          "reason": "",
          "result": true
        }
      },
      "args": [
        false
      ],
      "encrypted_with_aes_gcm": true,
      "field": "setLowPowerModeAction",
      "method": "set_low_power_mode",
      "payload": {
        "low_power_mode": false
      },
      "sent_domain": "DOMAIN_INFOTAINMENT",
      "step": 11
    }
  ],
  "old_navigation_gps_bug_check": {
    "enum_wrapper_callable": false,
    "enum_wrapper_type": "EnumTypeWrapper",
    "fixed_behavior": "navigation_gps_request completed and encoded order directly in the protobuf payload."
  },
  "purpose": "End-to-end mocked BLE protocol transcript for PR-8 nav/dashcam/power-mode commands."
}

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ tests/test_ble_nav_misc_commands.py:3 - The new test docstring commits the full live test vehicle VIN and local proxy hostname. For a public library, that is unnecessary evidence detail and expands the privacy footprint; redact it to a generic identifier while keeping the live-verification note.

🔧 Fix: Redact live test identifiers
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • Inspected the target diff for tesla_fleet_api/tesla/vehicle/commands.py and tests/test_ble_nav_misc_commands.py against base commit 0a8b33cccefb98bcdc5250c6709614378f89a4d8.
  • uv run pytest tests/test_ble_nav_misc_commands.py
  • Generated /tmp/no-mistakes-evidence/01KX3B3PZNN8XWG4NBEGKTANKB/ble_nav_misc_command_transcript.json by exercising all 11 target BLE command calls through VehicleBluetooth with mocked BLE transport, decrypting each signed command, and recording ACK/domain/payload details.
  • Removed transient pytest/cache artifacts created in the worktree after testing.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

firstmate crewmate added 3 commits July 9, 2026 21:57
Live-verified navigation_request, navigation_gps_request,
navigation_sc_request, navigation_waypoints_request,
navigation_gps_destination_request, dashcam_save_clip, flash_lights,
set_keep_accessory_power_mode, and set_low_power_mode against the test
car in one held BLE connection - all ACKed OK.

Fixed a real bug found live: navigation_gps_request called the
protobuf nested enum wrapper as if it were callable, raising
TypeError on every attempt before a message was ever sent.
@Bre77 Bre77 force-pushed the fm/tfa-ble-pr8-nav-misc branch from e0214e1 to 8a35dfb Compare July 9, 2026 11:58
@Bre77 Bre77 merged commit 629c16d into main Jul 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant