mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-08-21 16:23:46 +08:00
Kachow 2
This commit is contained in:
@@ -1,29 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
import json
|
||||
import jwt
|
||||
import random
|
||||
import string
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
|
||||
from datetime import datetime, timedelta, UTC
|
||||
from openpilot.common.api import api_get, get_key_pair
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.spinner import Spinner
|
||||
from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert
|
||||
from openpilot.system.hardware import HARDWARE, PC
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
|
||||
|
||||
UNREGISTERED_DONGLE_ID = "UnregisteredDevice"
|
||||
OFFROAD_UNREGISTERED_ALERT = "Offroad_UnregisteredHardware"
|
||||
KEYS = {"id_rsa": "RS256",
|
||||
"id_ecdsa": "ES256"}
|
||||
|
||||
|
||||
def api_get(*args, **kwargs):
|
||||
from openpilot.common.api import api_get as api_get_impl
|
||||
|
||||
return api_get_impl(*args, **kwargs)
|
||||
|
||||
|
||||
def get_key_pair() -> tuple[str, str, str] | tuple[None, None, None]:
|
||||
for key, algorithm in KEYS.items():
|
||||
private_path = Path(Paths.persist_root()) / "comma" / key
|
||||
public_path = Path(Paths.persist_root()) / "comma" / f"{key}.pub"
|
||||
if private_path.is_file() and public_path.is_file():
|
||||
return algorithm, private_path.read_text(), public_path.read_text()
|
||||
return None, None, None
|
||||
|
||||
|
||||
def _has_key_pair() -> bool:
|
||||
for key in KEYS:
|
||||
private_path = Path(Paths.persist_root()) / "comma" / key
|
||||
public_path = Path(Paths.persist_root()) / "comma" / f"{key}.pub"
|
||||
if private_path.is_file() and public_path.is_file():
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_registered_device() -> bool:
|
||||
dongle = Params().get("DongleId")
|
||||
return dongle not in (None, UNREGISTERED_DONGLE_ID)
|
||||
|
||||
|
||||
def _set_registration_alert(params: Params, dongle_id: str | None) -> None:
|
||||
show_alert = (dongle_id == UNREGISTERED_DONGLE_ID) and not PC
|
||||
if show_alert:
|
||||
from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert
|
||||
|
||||
set_offroad_alert(OFFROAD_UNREGISTERED_ALERT, True)
|
||||
else:
|
||||
params.remove(OFFROAD_UNREGISTERED_ALERT)
|
||||
|
||||
|
||||
def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
"""
|
||||
All devices built since March 2024 come with all
|
||||
@@ -42,13 +70,18 @@ def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
with open(Paths.persist_root()+"/comma/dongle_id") as f:
|
||||
dongle_id = f.read().strip()
|
||||
|
||||
# Create registration token, in the future, this key will make JWTs directly
|
||||
jwt_algo, private_key, public_key = get_key_pair()
|
||||
|
||||
if not public_key and not register_konik:
|
||||
if not _has_key_pair() and not register_konik:
|
||||
dongle_id = UNREGISTERED_DONGLE_ID
|
||||
cloudlog.warning("missing public key")
|
||||
elif dongle_id is None or register_konik:
|
||||
import json
|
||||
import jwt
|
||||
from datetime import datetime, timedelta, UTC
|
||||
from openpilot.common.spinner import Spinner
|
||||
|
||||
# Create registration token, in the future, this key will make JWTs directly
|
||||
jwt_algo, private_key, public_key = get_key_pair()
|
||||
|
||||
if show_spinner:
|
||||
spinner = Spinner()
|
||||
spinner.update("registering device")
|
||||
@@ -73,14 +106,14 @@ def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
while True:
|
||||
try:
|
||||
register_token = jwt.encode({'register': True, 'exp': datetime.now(UTC).replace(tzinfo=None) + timedelta(hours=1)},
|
||||
cast(str, private_key), algorithm=jwt_algo)
|
||||
private_key, algorithm=jwt_algo)
|
||||
cloudlog.info("getting pilotauth")
|
||||
resp = api_get("v2/pilotauth/", method='POST', timeout=15,
|
||||
imei=imei1, imei2=imei2, serial=serial, public_key=public_key, register_token=register_token)
|
||||
|
||||
if resp.status_code in (402, 403):
|
||||
cloudlog.info(f"Unable to register device, got {resp.status_code}")
|
||||
dongle_id = ''.join(random.choices(string.ascii_lowercase + string.digits, k=16))
|
||||
dongle_id = UNREGISTERED_DONGLE_ID
|
||||
else:
|
||||
dongleauth = json.loads(resp.text)
|
||||
dongle_id = dongleauth["dongle_id"]
|
||||
@@ -99,7 +132,7 @@ def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
if not register_konik and dongle_id != params.get("KonikDongleId"):
|
||||
params.put("DongleId", dongle_id)
|
||||
params.put("StockDongleId", dongle_id)
|
||||
set_offroad_alert("Offroad_UnregisteredHardware", (dongle_id == UNREGISTERED_DONGLE_ID) and not PC)
|
||||
_set_registration_alert(params, dongle_id)
|
||||
return dongle_id
|
||||
|
||||
|
||||
|
||||
+15
-12
@@ -1,18 +1,11 @@
|
||||
import errno
|
||||
import fcntl
|
||||
import os
|
||||
import sys
|
||||
import pathlib
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import tempfile
|
||||
import threading
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
|
||||
def unblock_stdout() -> None:
|
||||
import errno
|
||||
import fcntl
|
||||
import signal
|
||||
import sys
|
||||
|
||||
# get a non-blocking stdout
|
||||
child_pid, child_pty = os.forkpty()
|
||||
if child_pid != 0: # parent
|
||||
@@ -51,7 +44,17 @@ def write_onroad_params(started, params):
|
||||
|
||||
|
||||
def save_bootlog():
|
||||
import threading
|
||||
|
||||
def fn():
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
env = os.environ.copy()
|
||||
env['PARAMS_COPY_PATH'] = tmpdir
|
||||
|
||||
+52
-15
@@ -2,7 +2,6 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
import signal
|
||||
import sys
|
||||
@@ -24,26 +23,18 @@ def _append_boot_timing_line(line: str) -> None:
|
||||
|
||||
from cereal import car, log
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.common.utils import atomic_write
|
||||
from openpilot.common.params import Params, ParamKeyFlag, ParamKeyType
|
||||
from openpilot.common.text_window import TextWindow
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog
|
||||
from openpilot.system.manager.process import ensure_running
|
||||
from openpilot.system.manager.process_config import managed_processes
|
||||
from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID
|
||||
from openpilot.common.swaglog import cloudlog, add_file_handler
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system.version import get_build_metadata, terms_version, training_version
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
|
||||
_MANAGER_CORE_IMPORT_DONE = time.monotonic()
|
||||
|
||||
from openpilot.starpilot.common.starpilot_functions import starpilot_boot_functions, install_starpilot, uninstall_starpilot
|
||||
from openpilot.starpilot.common.starpilot_variables import (
|
||||
LEGACY_STARPILOT_PARAM_RENAMES,
|
||||
LEGACY_STARPILOT_STATS_KEY_RENAMES,
|
||||
get_starpilot_toggles,
|
||||
)
|
||||
|
||||
_MANAGER_IMPORT_DONE = time.monotonic()
|
||||
_manager_import_timing_line = (
|
||||
@@ -67,9 +58,23 @@ STARPILOT_PC_ROOT_MIGRATION_FLAG = Path("/data") / "starpilot_pc_root_v1"
|
||||
STARPILOT_PARAMS_CACHE_MIGRATION_FLAG = Path("/data") / "starpilot_params_cache_v1"
|
||||
STARPILOT_LEGACY_CACHE_MARKER_KEYS = ("RemapCancelToDistance",)
|
||||
STARPILOT_REMOVED_PARAM_KEYS = ("HumanFollowing",)
|
||||
UNREGISTERED_DONGLE_ID = "UnregisteredDevice"
|
||||
POWER_WATCHDOG_PATH = "/var/tmp/power_watchdog"
|
||||
LEGACY_CARMODEL_MIGRATIONS = {
|
||||
"CHEVROLET_BOLT_CC_2019_2021": "CHEVROLET_BOLT_CC_2018_2021",
|
||||
}
|
||||
LEGACY_STARPILOT_PARAM_RENAMES = {
|
||||
"FrogPilotApiToken": "StarPilotApiToken",
|
||||
"FrogPilotCarParams": "StarPilotCarParams",
|
||||
"FrogPilotCarParamsPersistent": "StarPilotCarParamsPersistent",
|
||||
"FrogPilotDongleId": "StarPilotDongleId",
|
||||
"FrogPilotStats": "StarPilotStats",
|
||||
}
|
||||
LEGACY_STARPILOT_STATS_KEY_RENAMES = {
|
||||
"FrogPilotDrives": "StarPilotDrives",
|
||||
"FrogPilotMeters": "StarPilotMeters",
|
||||
"FrogPilotSeconds": "StarPilotSeconds",
|
||||
}
|
||||
STARPILOT_STATS_DROP_KEYS = {"CurrentMonthsKilometers", "ResetStats"}
|
||||
STARPILOT_STATS_MAX_KEYS = {"LongestDistanceWithoutOverride", "MaxAcceleration"}
|
||||
|
||||
@@ -114,6 +119,30 @@ def _capture_manager_exception() -> None:
|
||||
cloudlog.exception("failed to capture manager exception")
|
||||
|
||||
|
||||
def _write_power_watchdog(timestamp: float) -> None:
|
||||
import tempfile
|
||||
|
||||
tmp_file_name = None
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile("w", dir=os.path.dirname(POWER_WATCHDOG_PATH), delete=False) as f:
|
||||
tmp_file_name = f.name
|
||||
f.write(str(timestamp))
|
||||
os.replace(tmp_file_name, POWER_WATCHDOG_PATH)
|
||||
tmp_file_name = None
|
||||
finally:
|
||||
if tmp_file_name is not None:
|
||||
try:
|
||||
os.unlink(tmp_file_name)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
def _get_starpilot_toggles(sm=None):
|
||||
from openpilot.starpilot.common.starpilot_variables import get_starpilot_toggles
|
||||
|
||||
return get_starpilot_toggles(sm)
|
||||
|
||||
|
||||
def _to_text(value):
|
||||
if value is None:
|
||||
return None
|
||||
@@ -285,6 +314,8 @@ def _copy_param_store_without_overwrite(source: Path, destination: Path) -> int:
|
||||
if not source.is_dir():
|
||||
return 0
|
||||
|
||||
import shutil
|
||||
|
||||
destination.mkdir(parents=True, exist_ok=True)
|
||||
copied_entries = 0
|
||||
for path in source.iterdir():
|
||||
@@ -402,6 +433,8 @@ def _merge_tree_without_overwrite(source: Path, destination: Path) -> int:
|
||||
if not source.exists():
|
||||
return moved_entries
|
||||
|
||||
import shutil
|
||||
|
||||
if not destination.exists():
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.move(str(source), str(destination))
|
||||
@@ -881,6 +914,8 @@ def manager_init() -> None:
|
||||
last_timing = _log_boot_timing("manager_init", "version_params", manager_init_start, last_timing)
|
||||
|
||||
# set dongle id
|
||||
from openpilot.system.athena.registration import register
|
||||
|
||||
reg_res = register(show_spinner=True)
|
||||
if reg_res:
|
||||
dongle_id = reg_res
|
||||
@@ -958,7 +993,7 @@ def manager_thread() -> None:
|
||||
last_timing = _log_boot_timing("manager_thread", "messaging", manager_thread_start, last_timing)
|
||||
|
||||
write_onroad_params(False, params)
|
||||
initial_toggles = get_starpilot_toggles()
|
||||
initial_toggles = _get_starpilot_toggles()
|
||||
last_timing = _log_boot_timing("manager_thread", "initial_toggles", manager_thread_start, last_timing)
|
||||
ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore, starpilot_toggles=initial_toggles)
|
||||
last_timing = _log_boot_timing("manager_thread", "initial_ensure_running", manager_thread_start, last_timing)
|
||||
@@ -974,7 +1009,7 @@ def manager_thread() -> None:
|
||||
|
||||
params_memory = Params(memory=True)
|
||||
|
||||
starpilot_toggles = get_starpilot_toggles()
|
||||
starpilot_toggles = _get_starpilot_toggles()
|
||||
last_timing = _log_boot_timing("manager_thread", "loop_toggles", manager_thread_start, last_timing)
|
||||
_log_boot_timing("manager_thread", "loop_ready", manager_thread_start, last_timing)
|
||||
|
||||
@@ -1024,8 +1059,7 @@ def manager_thread() -> None:
|
||||
# kick AGNOS power monitoring watchdog
|
||||
try:
|
||||
if sm.all_checks(['deviceState']):
|
||||
with atomic_write("/var/tmp/power_watchdog", "w", overwrite=True) as f:
|
||||
f.write(str(time.monotonic()))
|
||||
_write_power_watchdog(time.monotonic())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1048,7 +1082,7 @@ def manager_thread() -> None:
|
||||
break
|
||||
|
||||
# StarPilot variables
|
||||
starpilot_toggles = get_starpilot_toggles(sm)
|
||||
starpilot_toggles = _get_starpilot_toggles(sm)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -1087,6 +1121,9 @@ if __name__ == "__main__":
|
||||
except KeyboardInterrupt:
|
||||
print("got CTRL-C, exiting")
|
||||
except Exception:
|
||||
from openpilot.common.swaglog import add_file_handler
|
||||
from openpilot.common.text_window import TextWindow
|
||||
|
||||
add_file_handler(cloudlog)
|
||||
cloudlog.exception("Manager failed to start")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user