|
|
|
@ -2,9 +2,9 @@ |
|
|
|
|
import time |
|
|
|
|
import json |
|
|
|
|
import jwt |
|
|
|
|
import pyray as rl |
|
|
|
|
from pathlib import Path |
|
|
|
|
from concurrent.futures import ThreadPoolExecutor |
|
|
|
|
import threading |
|
|
|
|
import pyray as rl |
|
|
|
|
|
|
|
|
|
from datetime import datetime, timedelta, UTC |
|
|
|
|
from openpilot.common.api import api_get |
|
|
|
@ -12,19 +12,42 @@ from openpilot.common.params import Params |
|
|
|
|
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.system.ui.lib.application import gui_app |
|
|
|
|
from openpilot.system.ui.spinner import Spinner |
|
|
|
|
from openpilot.common.swaglog import cloudlog |
|
|
|
|
|
|
|
|
|
from openpilot.system.ui.spinner import Spinner |
|
|
|
|
from openpilot.system.ui.lib.application import gui_app |
|
|
|
|
|
|
|
|
|
UNREGISTERED_DONGLE_ID = "UnregisteredDevice" |
|
|
|
|
|
|
|
|
|
spinner: Spinner | None = None |
|
|
|
|
|
|
|
|
|
def is_registered_device() -> bool: |
|
|
|
|
dongle = Params().get("DongleId", encoding='utf-8') |
|
|
|
|
return dongle not in (None, UNREGISTERED_DONGLE_ID) |
|
|
|
|
|
|
|
|
|
def _get_dongle_id() -> str | None: |
|
|
|
|
dongle_id: str | None = Params().get("DongleId", encoding='utf8') |
|
|
|
|
def _show_spinner_window(end_evt: threading.Event): |
|
|
|
|
global spinner |
|
|
|
|
gui_app.init_window("registering device") |
|
|
|
|
spinner = Spinner() |
|
|
|
|
while not end_evt.is_set(): |
|
|
|
|
rl.begin_drawing() |
|
|
|
|
rl.clear_background(rl.BLACK) |
|
|
|
|
spinner.render() |
|
|
|
|
rl.end_drawing() |
|
|
|
|
gui_app.close() |
|
|
|
|
|
|
|
|
|
def register(show_spinner=False) -> str | None: |
|
|
|
|
""" |
|
|
|
|
All devices built since March 2024 come with all |
|
|
|
|
info stored in /persist/. This is kept around |
|
|
|
|
only for devices built before then. |
|
|
|
|
|
|
|
|
|
With a backend update to take serial number instead |
|
|
|
|
of dongle ID to some endpoints, this can be removed |
|
|
|
|
entirely. |
|
|
|
|
""" |
|
|
|
|
params = Params() |
|
|
|
|
|
|
|
|
|
dongle_id: str | None = params.get("DongleId", encoding='utf8') |
|
|
|
|
if dongle_id is None and Path(Paths.persist_root()+"/comma/dongle_id").is_file(): |
|
|
|
|
# not all devices will have this; added early in comma 3X production (2/28/24) |
|
|
|
|
with open(Paths.persist_root()+"/comma/dongle_id") as f: |
|
|
|
@ -34,19 +57,14 @@ def _get_dongle_id() -> str | None: |
|
|
|
|
if not pubkey.is_file(): |
|
|
|
|
dongle_id = UNREGISTERED_DONGLE_ID |
|
|
|
|
cloudlog.warning(f"missing public key: {pubkey}") |
|
|
|
|
elif dongle_id is None: |
|
|
|
|
global spinner |
|
|
|
|
spinner_thread = None |
|
|
|
|
if show_spinner: |
|
|
|
|
end_evt = threading.Event() |
|
|
|
|
spinner_thread = threading.Thread(target=_show_spinner_window, args=(end_evt,)) |
|
|
|
|
spinner_thread.start() |
|
|
|
|
|
|
|
|
|
return dongle_id |
|
|
|
|
|
|
|
|
|
def do_register(spinner = None, done_event=None) -> str | None: |
|
|
|
|
""" |
|
|
|
|
All devices built since March 2024 come with all |
|
|
|
|
info stored in /persist/. This is kept around |
|
|
|
|
only for devices built before then. |
|
|
|
|
|
|
|
|
|
With a backend update to take serial number instead |
|
|
|
|
of dongle ID to some endpoints, this can be removed |
|
|
|
|
entirely. |
|
|
|
|
""" |
|
|
|
|
# Create registration token, in the future, this key will make JWTs directly |
|
|
|
|
with open(Paths.persist_root()+"/comma/id_rsa.pub") as f1, open(Paths.persist_root()+"/comma/id_rsa") as f2: |
|
|
|
|
public_key = f1.read() |
|
|
|
@ -67,7 +85,6 @@ def do_register(spinner = None, done_event=None) -> str | None: |
|
|
|
|
if time.monotonic() - start_time > 60 and spinner: |
|
|
|
|
spinner.set_text(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})") |
|
|
|
|
|
|
|
|
|
dongle_id = None |
|
|
|
|
backoff = 0 |
|
|
|
|
start_time = time.monotonic() |
|
|
|
|
while True: |
|
|
|
@ -92,29 +109,12 @@ def do_register(spinner = None, done_event=None) -> str | None: |
|
|
|
|
if time.monotonic() - start_time > 60 and spinner: |
|
|
|
|
spinner.set_text(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})") |
|
|
|
|
|
|
|
|
|
return dongle_id |
|
|
|
|
|
|
|
|
|
def register(show_spinner=False) -> str | None: |
|
|
|
|
dongle_id = _get_dongle_id() |
|
|
|
|
if not dongle_id: |
|
|
|
|
if show_spinner: |
|
|
|
|
with ThreadPoolExecutor(max_workers=1) as executor: |
|
|
|
|
gui_app.init_window("Register") |
|
|
|
|
spinner = Spinner() |
|
|
|
|
spinner.set_text("registering device") |
|
|
|
|
future = executor.submit(do_register, spinner) |
|
|
|
|
while not future.done(): |
|
|
|
|
rl.begin_drawing() |
|
|
|
|
rl.clear_background(rl.BLACK) |
|
|
|
|
spinner.render() |
|
|
|
|
rl.end_drawing() |
|
|
|
|
gui_app.close() |
|
|
|
|
dongle_id = future.result() |
|
|
|
|
else: |
|
|
|
|
dongle_id = do_register() |
|
|
|
|
if spinner_thread: |
|
|
|
|
end_evt.set() |
|
|
|
|
spinner_thread.join() |
|
|
|
|
|
|
|
|
|
if dongle_id: |
|
|
|
|
Params().put("DongleId", dongle_id) |
|
|
|
|
params.put("DongleId", dongle_id) |
|
|
|
|
set_offroad_alert("Offroad_UnofficialHardware", (dongle_id == UNREGISTERED_DONGLE_ID) and not PC) |
|
|
|
|
return dongle_id |
|
|
|
|
|
|
|
|
|