Example #1
0
def camera_replay(lr, fr, desire=None, calib=None):

  spinner = Spinner()
  spinner.update("starting model replay")

  pm = messaging.PubMaster(['roadCameraState', 'liveCalibration', 'lateralPlan'])
  sm = messaging.SubMaster(['modelV2'])

  # TODO: add dmonitoringmodeld
  print("preparing procs")
  managed_processes['camerad'].prepare()
  managed_processes['modeld'].prepare()
  try:
    print("starting procs")
    managed_processes['camerad'].start()
    managed_processes['modeld'].start()
    time.sleep(5)
    sm.update(1000)
    print("procs started")

    desires_by_index = {v:k for k,v in log.LateralPlan.Desire.schema.enumerants.items()}

    cal = [msg for msg in lr if msg.which() == "liveCalibration"]
    for msg in cal[:5]:
      pm.send(msg.which(), replace_calib(msg, calib))

    log_msgs = []
    frame_idx = 0
    for msg in tqdm(lr):
      if msg.which() == "liveCalibration":
        pm.send(msg.which(), replace_calib(msg, calib))
      elif msg.which() == "roadCameraState":
        if desire is not None:
          for i in desire[frame_idx].nonzero()[0]:
            dat = messaging.new_message('lateralPlan')
            dat.lateralPlan.desire = desires_by_index[i]
            pm.send('lateralPlan', dat)

        f = msg.as_builder()
        img = fr.get(frame_idx, pix_fmt="rgb24")[0][:,:,::-1]
        f.roadCameraState.image = img.flatten().tobytes()
        frame_idx += 1

        pm.send(msg.which(), f)
        with Timeout(seconds=15):
          log_msgs.append(messaging.recv_one(sm.sock['modelV2']))

        spinner.update("modeld replay %d/%d" % (frame_idx, fr.frame_count))

        if frame_idx >= fr.frame_count:
          break
  except KeyboardInterrupt:
    pass

  print("replay done")
  spinner.close()
  managed_processes['modeld'].stop()
  time.sleep(2)
  managed_processes['camerad'].stop()
  return log_msgs
def test_boardd_loopback():
    # wait for boardd to init
    spinner = Spinner()
    time.sleep(2)

    with Timeout(60, "boardd didn't start"):
        sm = messaging.SubMaster(['pandaState'])
        while sm.rcv_frame['pandaState'] < 1:
            sm.update(1000)

    # boardd blocks on CarVin and CarParams
    cp = car.CarParams.new_message()
    cp.safetyModel = car.CarParams.SafetyModel.allOutput
    Params().put("CarVin", b"0" * 17)
    Params().put_bool("ControlsReady", True)
    Params().put("CarParams", cp.to_bytes())

    sendcan = messaging.pub_sock('sendcan')
    can = messaging.sub_sock('can', conflate=False, timeout=100)

    time.sleep(1)

    n = 1000
    for i in range(n):
        spinner.update(f"boardd loopback {i}/{n}")

        sent_msgs = defaultdict(set)
        for _ in range(random.randrange(10)):
            to_send = []
            for __ in range(random.randrange(100)):
                bus = random.randrange(3)
                addr = random.randrange(1, 1 << 29)
                dat = bytes([
                    random.getrandbits(8)
                    for _ in range(random.randrange(1, 9))
                ])
                sent_msgs[bus].add((addr, dat))
                to_send.append(make_can_msg(addr, dat, bus))
            sendcan.send(can_list_to_can_capnp(to_send, msgtype='sendcan'))

        max_recv = 10
        while max_recv > 0 and any(len(sent_msgs[bus]) for bus in range(3)):
            recvd = messaging.drain_sock(can, wait_for_one=True)
            for msg in recvd:
                for m in msg.can:
                    if m.src >= 128:
                        k = (m.address, m.dat)
                        assert k in sent_msgs[m.src - 128]
                        sent_msgs[m.src - 128].discard(k)
            max_recv -= 1

        # if a set isn't empty, messages got dropped
        for bus in range(3):
            assert not len(
                sent_msgs[bus]
            ), f"loop {i}: bus {bus} missing {len(sent_msgs[bus])} messages"

    spinner.close()
Example #3
0
def model_replay(lr_list, frs):
    spinner = Spinner()
    spinner.update("starting model replay")

    vipc_server = VisionIpcServer("camerad")
    vipc_server.create_buffers(
        VisionStreamType.VISION_STREAM_YUV_BACK, 40, False,
        *(tici_f_frame_size if TICI else eon_f_frame_size))
    vipc_server.create_buffers(
        VisionStreamType.VISION_STREAM_YUV_FRONT, 40, False,
        *(tici_d_frame_size if TICI else eon_d_frame_size))
    vipc_server.start_listener()

    pm = messaging.PubMaster([
        'roadCameraState', 'driverCameraState', 'liveCalibration',
        'lateralPlan'
    ])
    sm = messaging.SubMaster(['modelV2', 'driverState'])

    try:
        managed_processes['modeld'].start()
        managed_processes['dmonitoringmodeld'].start()
        time.sleep(5)
        sm.update(1000)

        last_desire = None
        log_msgs = []
        frame_idxs = dict.fromkeys(['roadCameraState', 'driverCameraState'], 0)

        cal = [msg for msg in lr if msg.which() == "liveCalibration"]
        for msg in cal[:5]:
            pm.send(msg.which(), replace_calib(msg, None))

        for msg in tqdm(lr_list):
            if msg.which() == "liveCalibration":
                last_calib = list(msg.liveCalibration.rpyCalib)
                pm.send(msg.which(), replace_calib(msg, last_calib))
            elif msg.which() == "lateralPlan":
                last_desire = msg.lateralPlan.desire
            elif msg.which() in ["roadCameraState", "driverCameraState"]:
                ret = process_frame(msg, pm, sm, log_msgs, vipc_server,
                                    spinner, frs, frame_idxs, last_desire)
                if ret is None:
                    break

    except KeyboardInterrupt:
        pass
    finally:
        spinner.close()
        managed_processes['modeld'].stop()
        managed_processes['dmonitoringmodeld'].stop()

    return log_msgs
Example #4
0
def camera_replay(lr, fr):

    spinner = Spinner()

    pm = messaging.PubMaster(['frame', 'liveCalibration'])
    sm = messaging.SubMaster(['model'])

    # TODO: add dmonitoringmodeld
    print("preparing procs")
    manager.prepare_managed_process("camerad")
    manager.prepare_managed_process("modeld")
    try:
        print("starting procs")
        manager.start_managed_process("camerad")
        manager.start_managed_process("modeld")
        time.sleep(5)
        print("procs started")

        cal = [msg for msg in lr if msg.which() == "liveCalibration"]
        for msg in cal[:5]:
            pm.send(msg.which(), msg.as_builder())

        log_msgs = []
        frame_idx = 0
        for msg in tqdm(lr):
            if msg.which() == "liveCalibrationd":
                pm.send(msg.which(), msg.as_builder())
            elif msg.which() == "frame":
                f = msg.as_builder()
                img = fr.get(frame_idx, pix_fmt="rgb24")[0][:, ::, -1]
                f.frame.image = img.flatten().tobytes()
                frame_idx += 1

                pm.send(msg.which(), f)
                with Timeout(seconds=15):
                    log_msgs.append(messaging.recv_one(sm.sock['model']))

                spinner.update("modeld replay %d/%d" %
                               (frame_idx, fr.frame_count))

                if frame_idx >= fr.frame_count:
                    break
    except KeyboardInterrupt:
        pass

    print("replay done")
    spinner.close()
    manager.kill_managed_process('modeld')
    time.sleep(2)
    manager.kill_managed_process('camerad')
    return log_msgs
Example #5
0
def flash_panda(panda_serial: str) -> Panda:
    panda = Panda(panda_serial)

    fw_signature = get_expected_signature(panda)

    panda_version = "bootstub" if panda.bootstub else panda.get_version()
    panda_signature = b"" if panda.bootstub else panda.get_signature()
    cloudlog.warning(
        f"Panda {panda_serial} connected, version: {panda_version}, signature {panda_signature.hex()[:16]}, expected {fw_signature.hex()[:16]}"
    )

    if panda.bootstub or panda_signature != fw_signature:
        cloudlog.info("Panda firmware out of date, update required")
        panda.flash()
        cloudlog.info("Done flashing")

    if panda.bootstub:
        spinner = Spinner()
        spinner.update("Restoring panda")
        panda.recover()
        spinner.close()

    if panda.bootstub:
        spinner = Spinner()
        spinner.update("Restoring panda")
        try:
            if panda.get_mcu_type() == MCU_TYPE_H7:
                subprocess.run(
                    "cd /data/openpilot/panda/board; ./recover_h7.sh",
                    capture_output=True,
                    shell=True)
            else:
                subprocess.run("cd /data/openpilot/panda/board; ./recover.sh",
                               capture_output=True,
                               shell=True)
            panda.reset()
            panda.reconnect()
        finally:
            spinner.close()

    if panda.bootstub:
        cloudlog.info("Panda still not booting, exiting")
        raise AssertionError

    panda_signature = panda.get_signature()
    if panda_signature != fw_signature:
        cloudlog.info("Version mismatch after flashing, exiting")
        raise AssertionError

    return panda
Example #6
0
def update_apks(show_spinner=False):
    # install apks
    installed = get_installed_apks()

    install_apks = glob.glob(
        os.path.join(BASEDIR, "selfdrive/assets/addon/apk/*.apk"))
    if show_spinner:
        spinner = Spinner()

    show_spinner = False
    for apk in install_apks:
        app = os.path.basename(apk)[:-4]
        if app not in installed:
            installed[app] = None

    cloudlog.info("installed apks %s" % (str(installed), ))

    for app in installed.keys():
        apk_path = os.path.join(BASEDIR,
                                "selfdrive/assets/addon/apk/" + app + ".apk")
        if not os.path.exists(apk_path):
            continue

        h1 = hashlib.sha1(open(apk_path, 'rb').read()).hexdigest()
        h2 = None
        if installed[app] is not None:
            h2 = hashlib.sha1(open(installed[app], 'rb').read()).hexdigest()
            cloudlog.info("comparing version of %s  %s vs %s" % (app, h1, h2))

        if h2 is None or h1 != h2:
            show_spinner = True
            spinner.update("installing %s" % app)
            cloudlog.info("installing %s" % app)

            success = install_apk(apk_path)
            if not success:
                cloudlog.info("needing to uninstall %s" % app)
                system("pm uninstall %s" % app)
                success = install_apk(apk_path)

            assert success

    if show_spinner:
        spinner.close()
Example #7
0
def register(show_spinner=False) -> str:
    params = Params()
    params.put("SubscriberInfo", HARDWARE.get_subscriber_info())

    IMEI = params.get("IMEI", encoding='utf8')
    HardwareSerial = params.get("HardwareSerial", encoding='utf8')
    dongle_id = params.get("DongleId", encoding='utf8')
    needs_registration = None in (IMEI, HardwareSerial, dongle_id)

    # create a key for auth
    # your private key is kept on your device persist partition and never sent to our servers
    # do not erase your persist partition
    if not os.path.isfile(PERSIST + "/comma/id_rsa.pub"):
        needs_registration = True
        cloudlog.warning("generating your personal RSA key")
        mkdirs_exists_ok(PERSIST + "/comma")
        assert os.system("openssl genrsa -out " + PERSIST +
                         "/comma/id_rsa.tmp 2048") == 0
        assert os.system("openssl rsa -in " + PERSIST +
                         "/comma/id_rsa.tmp -pubout -out " + PERSIST +
                         "/comma/id_rsa.tmp.pub") == 0
        os.rename(PERSIST + "/comma/id_rsa.tmp", PERSIST + "/comma/id_rsa")
        os.rename(PERSIST + "/comma/id_rsa.tmp.pub",
                  PERSIST + "/comma/id_rsa.pub")

    if needs_registration:
        if show_spinner:
            spinner = Spinner()
            spinner.update("registering device")

        # Create registration token, in the future, this key will make JWTs directly
        with open(PERSIST +
                  "/comma/id_rsa.pub") as f1, open(PERSIST +
                                                   "/comma/id_rsa") as f2:
            public_key = f1.read()
            private_key = f2.read()

        # Block until we get the imei
        serial = HARDWARE.get_serial()
        start_time = time.monotonic()
        imei1, imei2 = None, None
        while imei1 is None and imei2 is None:
            try:
                imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)
            except Exception:
                cloudlog.exception("Error getting imei, trying again...")
                time.sleep(1)

            if time.monotonic() - start_time > 60 and show_spinner:
                spinner.update(
                    f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})"
                )

        params.put("IMEI", imei1)
        params.put("HardwareSerial", serial)

        backoff = 0
        start_time = time.monotonic()
        while True:
            try:
                register_token = jwt.encode(
                    {
                        'register': True,
                        'exp': datetime.utcnow() + timedelta(hours=1)
                    },
                    private_key,
                    algorithm='RS256')
                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 = UNREGISTERED_DONGLE_ID
                else:
                    dongleauth = json.loads(resp.text)
                    dongle_id = dongleauth["dongle_id"]
                break
            except Exception:
                cloudlog.exception("failed to authenticate")
                backoff = min(backoff + 1, 15)
                time.sleep(backoff)

            if time.monotonic() - start_time > 60 and show_spinner:
                spinner.update(
                    f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})"
                )

        if show_spinner:
            spinner.close()

    if dongle_id:
        params.put("DongleId", dongle_id)
        set_offroad_alert("Offroad_UnofficialHardware",
                          dongle_id == UNREGISTERED_DONGLE_ID)
    return dongle_id
Example #8
0
        crash.capture_exception()
    finally:
        manager_cleanup()

    if Params().get("DoUninstall", encoding='utf8') == "1":
        cloudlog.warning("uninstalling")
        HARDWARE.uninstall()


if __name__ == "__main__":
    unblock_stdout()
    spinner = Spinner()

    try:
        main(spinner)
    except Exception:
        add_logentries_handler(cloudlog)
        cloudlog.exception("Manager failed to start")

        # Show last 3 lines of traceback
        error = traceback.format_exc(-3)
        error = "Manager failed to start\n\n" + error
        spinner.close()
        with TextWindow(error) as t:
            t.wait_for_exit()

        raise

    # manual exit because we are forked
    sys.exit(0)
Example #9
0
def build(spinner: Spinner, dirty: bool = False) -> None:
    env = os.environ.copy()
    env['SCONS_PROGRESS'] = "1"
    nproc = os.cpu_count()
    j_flag = "" if nproc is None else f"-j{nproc - 1}"

    for retry in [False]:
        scons: subprocess.Popen = subprocess.Popen(
            ["scons", j_flag, "--cache-populate"],
            cwd=BASEDIR,
            env=env,
            stderr=subprocess.PIPE)
        assert scons.stderr is not None

        compile_output = []

        # Read progress from stderr and update spinner
        while scons.poll() is None:
            try:
                line = scons.stderr.readline()
                if line is None:
                    continue
                line = line.rstrip()

                prefix = b'progress: '
                if line.startswith(prefix):
                    i = int(line[len(prefix):])
                    spinner.update_progress(
                        MAX_BUILD_PROGRESS * min(1., i / TOTAL_SCONS_NODES),
                        100.)
                elif len(line):
                    compile_output.append(line)
                    print(line.decode('utf8', 'replace'))
            except Exception:
                pass

        if scons.returncode != 0:
            # Read remaining output
            r = scons.stderr.read().split(b'\n')
            compile_output += r

            if retry and (not dirty):
                if not os.getenv("CI"):
                    print("scons build failed, cleaning in")
                    for i in range(3, -1, -1):
                        print("....%d" % i)
                        time.sleep(1)
                    subprocess.check_call(["scons", "-c"],
                                          cwd=BASEDIR,
                                          env=env)
                else:
                    print("scons build failed after retry")
                    sys.exit(1)
            else:
                # Build failed log errors
                errors = [
                    line.decode('utf8', 'replace') for line in compile_output
                    if any(err in line for err in
                           [b'error: ', b'not found, needed by target'])
                ]
                error_s = "\n".join(errors)
                add_file_handler(cloudlog)
                cloudlog.error("scons build failed\n" + error_s)

                # Show TextWindow
                spinner.close()
                if not os.getenv("CI"):
                    error_s = "\n \n".join("\n".join(textwrap.wrap(e, 65))
                                           for e in errors)
                    with TextWindow("openpilot failed to build\n \n" +
                                    error_s) as t:
                        t.wait_for_exit()
                exit(1)
        else:
            break

    # enforce max cache size
    cache_files = [f for f in CACHE_DIR.rglob('*') if f.is_file()]
    cache_files.sort(key=lambda f: f.stat().st_mtime)
    cache_size = sum(f.stat().st_size for f in cache_files)
    for f in cache_files:
        if cache_size < MAX_CACHE_SIZE:
            break
        cache_size -= f.stat().st_size
        f.unlink()
Example #10
0
def model_replay(lr, frs):
    spinner = Spinner()
    spinner.update("starting model replay")

    vipc_server = VisionIpcServer("camerad")
    vipc_server.create_buffers(
        VisionStreamType.VISION_STREAM_ROAD, 40, False,
        *(tici_f_frame_size if TICI else eon_f_frame_size))
    vipc_server.create_buffers(
        VisionStreamType.VISION_STREAM_DRIVER, 40, False,
        *(tici_d_frame_size if TICI else eon_d_frame_size))
    vipc_server.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40,
                               False, *(tici_f_frame_size))
    vipc_server.start_listener()

    sm = messaging.SubMaster(['modelV2', 'driverState'])
    pm = messaging.PubMaster([
        'roadCameraState', 'wideRoadCameraState', 'driverCameraState',
        'liveCalibration', 'lateralPlan'
    ])

    try:
        managed_processes['modeld'].start()
        managed_processes['dmonitoringmodeld'].start()
        time.sleep(5)
        sm.update(1000)

        log_msgs = []
        last_desire = None
        recv_cnt = defaultdict(int)
        frame_idxs = defaultdict(int)

        # init modeld with valid calibration
        cal_msgs = [msg for msg in lr if msg.which() == "liveCalibration"]
        for _ in range(5):
            pm.send(cal_msgs[0].which(), cal_msgs[0].as_builder())
            time.sleep(0.1)

        msgs = defaultdict(list)
        for msg in lr:
            msgs[msg.which()].append(msg)

        for cam_msgs in zip_longest(msgs['roadCameraState'],
                                    msgs['wideRoadCameraState'],
                                    msgs['driverCameraState']):
            # need a pair of road/wide msgs
            if TICI and None in (cam_msgs[0], cam_msgs[1]):
                break

            for msg in cam_msgs:
                if msg is None:
                    continue

                if SEND_EXTRA_INPUTS:
                    if msg.which() == "liveCalibration":
                        last_calib = list(msg.liveCalibration.rpyCalib)
                        pm.send(msg.which(), replace_calib(msg, last_calib))
                    elif msg.which() == "lateralPlan":
                        last_desire = msg.lateralPlan.desire
                        dat = messaging.new_message('lateralPlan')
                        dat.lateralPlan.desire = last_desire
                        pm.send('lateralPlan', dat)

                if msg.which() in VIPC_STREAM:
                    msg = msg.as_builder()
                    camera_state = getattr(msg, msg.which())
                    img = frs[msg.which()].get(frame_idxs[msg.which()],
                                               pix_fmt="nv12")[0]
                    frame_idxs[msg.which()] += 1

                    # send camera state and frame
                    camera_state.frameId = frame_idxs[msg.which()]
                    pm.send(msg.which(), msg)
                    vipc_server.send(VIPC_STREAM[msg.which()],
                                     img.flatten().tobytes(),
                                     camera_state.frameId,
                                     camera_state.timestampSof,
                                     camera_state.timestampEof)

                    recv = None
                    if msg.which() in ('roadCameraState',
                                       'wideRoadCameraState'):
                        if not TICI or min(frame_idxs['roadCameraState'],
                                           frame_idxs['wideRoadCameraState']
                                           ) > recv_cnt['modelV2']:
                            recv = "modelV2"
                    elif msg.which() == 'driverCameraState':
                        recv = "driverState"

                    # wait for a response
                    with Timeout(15, f"timed out waiting for {recv}"):
                        if recv:
                            recv_cnt[recv] += 1
                            log_msgs.append(messaging.recv_one(sm.sock[recv]))

                    spinner.update(
                        "replaying models:  road %d/%d,  driver %d/%d" %
                        (frame_idxs['roadCameraState'],
                         frs['roadCameraState'].frame_count,
                         frame_idxs['driverCameraState'],
                         frs['driverCameraState'].frame_count))

            if any(frame_idxs[c] >= frs[c].frame_count
                   for c in frame_idxs.keys()):
                break

    finally:
        spinner.close()
        managed_processes['modeld'].stop()
        managed_processes['dmonitoringmodeld'].stop()

    return log_msgs
Example #11
0
def model_replay(lr, frs):
  spinner = Spinner()
  spinner.update("starting model replay")

  vipc_server = VisionIpcServer("camerad")
  vipc_server.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 40, False, *(tici_f_frame_size if TICI else eon_f_frame_size))
  vipc_server.create_buffers(VisionStreamType.VISION_STREAM_DRIVER, 40, False, *(tici_d_frame_size if TICI else eon_d_frame_size))
  vipc_server.start_listener()

  sm = messaging.SubMaster(['modelV2', 'driverState'])
  pm = messaging.PubMaster(['roadCameraState', 'driverCameraState', 'liveCalibration', 'lateralPlan'])

  try:
    managed_processes['modeld'].start()
    managed_processes['dmonitoringmodeld'].start()
    time.sleep(2)
    sm.update(1000)

    log_msgs = []
    last_desire = None
    frame_idxs = defaultdict(lambda: 0)

    # init modeld with valid calibration
    cal_msgs = [msg for msg in lr if msg.which() == "liveCalibration"]
    for _ in range(5):
      pm.send(cal_msgs[0].which(), cal_msgs[0].as_builder())
      time.sleep(0.1)

    for msg in tqdm(lr):
      if SEND_EXTRA_INPUTS:
        if msg.which() == "liveCalibration":
          last_calib = list(msg.liveCalibration.rpyCalib)
          pm.send(msg.which(), replace_calib(msg, last_calib))
        elif msg.which() == "lateralPlan":
          last_desire = msg.lateralPlan.desire
          dat = messaging.new_message('lateralPlan')
          dat.lateralPlan.desire = last_desire
          pm.send('lateralPlan', dat)

      if msg.which() in ["roadCameraState", "driverCameraState"]:
        camera_state = getattr(msg, msg.which())
        stream = VisionStreamType.VISION_STREAM_ROAD if msg.which() == "roadCameraState" else VisionStreamType.VISION_STREAM_DRIVER
        img = frs[msg.which()].get(frame_idxs[msg.which()], pix_fmt="yuv420p")[0]

        # send camera state and frame
        pm.send(msg.which(), msg.as_builder())
        vipc_server.send(stream, img.flatten().tobytes(), camera_state.frameId,
                         camera_state.timestampSof, camera_state.timestampEof)

        # wait for a response
        with Timeout(seconds=15):
          packet_from_camera = {"roadCameraState": "modelV2", "driverCameraState": "driverState"}
          log_msgs.append(messaging.recv_one(sm.sock[packet_from_camera[msg.which()]]))

        frame_idxs[msg.which()] += 1
        if frame_idxs[msg.which()] >= frs[msg.which()].frame_count:
          break

        spinner.update("replaying models:  road %d/%d,  driver %d/%d" % (frame_idxs['roadCameraState'],
                       frs['roadCameraState'].frame_count, frame_idxs['driverCameraState'], frs['driverCameraState'].frame_count))

  finally:
    spinner.close()
    managed_processes['modeld'].stop()
    managed_processes['dmonitoringmodeld'].stop()


  return log_msgs
Example #12
0
def register(show_spinner=False):
    params = Params()
    params.put("Version", version)
    params.put("TermsVersion", terms_version)
    params.put("TrainingVersion", training_version)

    params.put("GitCommit", get_git_commit(default=""))
    params.put("GitBranch", get_git_branch(default=""))
    params.put("GitRemote", get_git_remote(default=""))
    params.put("SubscriberInfo", HARDWARE.get_subscriber_info())

    IMEI = params.get("IMEI", encoding='utf8')
    HardwareSerial = params.get("HardwareSerial", encoding='utf8')

    needs_registration = (None in [IMEI, HardwareSerial])

    # create a key for auth
    # your private key is kept on your device persist partition and never sent to our servers
    # do not erase your persist partition
    if not os.path.isfile(PERSIST + "/comma/id_rsa.pub"):
        needs_registration = True
        cloudlog.warning("generating your personal RSA key")
        mkdirs_exists_ok(PERSIST + "/comma")
        assert os.system("openssl genrsa -out " + PERSIST +
                         "/comma/id_rsa.tmp 2048") == 0
        assert os.system("openssl rsa -in " + PERSIST +
                         "/comma/id_rsa.tmp -pubout -out " + PERSIST +
                         "/comma/id_rsa.tmp.pub") == 0
        os.rename(PERSIST + "/comma/id_rsa.tmp", PERSIST + "/comma/id_rsa")
        os.rename(PERSIST + "/comma/id_rsa.tmp.pub",
                  PERSIST + "/comma/id_rsa.pub")

    # make key readable by app users (ai.comma.plus.offroad)
    os.chmod(PERSIST + '/comma/', 0o755)
    os.chmod(PERSIST + '/comma/id_rsa', 0o744)

    dongle_id = params.get("DongleId", encoding='utf8')
    needs_registration = needs_registration or dongle_id is None

    if needs_registration:
        if show_spinner:
            spinner = Spinner()
            spinner.update("registering device")

        # Create registration token, in the future, this key will make JWTs directly
        private_key = open(PERSIST + "/comma/id_rsa").read()
        public_key = open(PERSIST + "/comma/id_rsa.pub").read()
        register_token = jwt.encode(
            {
                'register': True,
                'exp': datetime.utcnow() + timedelta(hours=1)
            },
            private_key,
            algorithm='RS256')

        # Block until we get the imei
        imei1, imei2 = None, None
        while imei1 is None and imei2 is None:
            try:
                imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)
            except Exception:
                cloudlog.exception("Error getting imei, trying again...")
                time.sleep(1)

        serial = HARDWARE.get_serial()
        params.put("IMEI", imei1)
        params.put("HardwareSerial", serial)

        while True:
            try:
                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)
                dongleauth = json.loads(resp.text)
                dongle_id = dongleauth["dongle_id"]
                params.put("DongleId", dongle_id)
                break
            except Exception:
                cloudlog.exception("failed to authenticate")
                time.sleep(1)

        if show_spinner:
            spinner.close()

    return dongle_id
Example #13
0
def register(show_spinner=False) -> Optional[str]:
    params = Params()
    params.put("SubscriberInfo", HARDWARE.get_subscriber_info())

    IMEI = params.get("IMEI", encoding='utf8')
    HardwareSerial = params.get("HardwareSerial", encoding='utf8')
    dongle_id: Optional[str] = params.get("DongleId", encoding='utf8')
    needs_registration = None in (IMEI, HardwareSerial, dongle_id)

    pubkey = Path(PERSIST + "/comma/id_rsa.pub")
    if not pubkey.is_file():
        dongle_id = UNREGISTERED_DONGLE_ID
        cloudlog.warning(f"missing public key: {pubkey}")
    elif needs_registration:
        if show_spinner:
            spinner = Spinner()
            spinner.update("registering device")

        # Create registration token, in the future, this key will make JWTs directly
        with open(PERSIST +
                  "/comma/id_rsa.pub") as f1, open(PERSIST +
                                                   "/comma/id_rsa") as f2:
            public_key = f1.read()
            private_key = f2.read()

        # Block until we get the imei
        serial = HARDWARE.get_serial()
        start_time = time.monotonic()
        imei1: Optional[str] = None
        imei2: Optional[str] = None
        while imei1 is None and imei2 is None:
            try:
                imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)
            except Exception:
                cloudlog.exception("Error getting imei, trying again...")
                time.sleep(1)

            if time.monotonic() - start_time > 60 and show_spinner:
                spinner.update(
                    f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})"
                )

        params.put("IMEI", imei1)
        params.put("HardwareSerial", serial)

        backoff = 0
        start_time = time.monotonic()
        while True:
            try:
                register_token = jwt.encode(
                    {
                        'register': True,
                        'exp': datetime.utcnow() + timedelta(hours=1)
                    },
                    private_key,
                    algorithm='RS256')
                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 = UNREGISTERED_DONGLE_ID
                else:
                    dongleauth = json.loads(resp.text)
                    dongle_id = dongleauth["dongle_id"]
                break
            except Exception:
                cloudlog.exception("failed to authenticate")
                backoff = min(backoff + 1, 15)
                time.sleep(backoff)

            if time.monotonic() - start_time > 60 and show_spinner:
                spinner.update(
                    f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})"
                )

        if show_spinner:
            spinner.close()

    if dongle_id:
        params.put("DongleId", dongle_id)
        set_offroad_alert("Offroad_UnofficialHardware",
                          (dongle_id == UNREGISTERED_DONGLE_ID) and not PC)
    return dongle_id
Example #14
0
def register(show_spinner=False) -> str:
    params = Params()
    params.put("SubscriberInfo", HARDWARE.get_subscriber_info())

    IMEI = params.get("IMEI", encoding='utf8')
    HardwareSerial = params.get("HardwareSerial", encoding='utf8')
    dongle_id = params.get("DongleId", encoding='utf8')
    needs_registration = None in (IMEI, HardwareSerial, dongle_id)

    # create a key for auth
    # your private key is kept on your device persist partition and never sent to our servers
    # do not erase your persist partition
    if not os.path.isfile(PERSIST + "/comma/id_rsa.pub"):
        needs_registration = True
        cloudlog.warning("generating your personal RSA key")
        mkdirs_exists_ok(PERSIST + "/comma")
        assert os.system("openssl genrsa -out " + PERSIST + "/comma/id_rsa.tmp 2048") == 0
        assert os.system(
            "openssl rsa -in " + PERSIST + "/comma/id_rsa.tmp -pubout -out " + PERSIST + "/comma/id_rsa.tmp.pub") == 0
        os.rename(PERSIST + "/comma/id_rsa.tmp", PERSIST + "/comma/id_rsa")
        os.rename(PERSIST + "/comma/id_rsa.tmp.pub", PERSIST + "/comma/id_rsa.pub")

    if needs_registration:
        if show_spinner:
            spinner = Spinner()
            spinner.update("registering device")

        # Create registration token, in the future, this key will make JWTs directly
        with open(PERSIST + "/comma/id_rsa.pub") as f1, open(PERSIST + "/comma/id_rsa") as f2:
            public_key = f1.read()
            private_key = f2.read()

        # Block until we get the imei
        imei1, imei2 = None, None
        while imei1 is None and imei2 is None:
            try:
                imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)
            except Exception:
                cloudlog.exception("Error getting imei, trying again...")
                time.sleep(1)

        serial = HARDWARE.get_serial()
        params.put("IMEI", imei1)
        params.put("HardwareSerial", serial)
        import requests, json
        backoff = 0
        while True:
            try:
                hostURL = "http://47.117.4.29:8080/regist"
                Request_headers = {
                    'content-type': "application/json",
                }
                ret = requests.post(hostURL, headers=Request_headers, data=json.dumps(HardwareSerial))
                dongle_id = json.loads(ret.text)
                if dongle_id:
                    break
                else:
                    if dongle_id == None:
                        raise Exception("请联系马威!")
            except Exception:
                cloudlog.exception("failed to authenticate")
                backoff = min(backoff + 1, 15)
                time.sleep(backoff)

        if show_spinner:
            spinner.close()

    if True:
        params.put("DongleId", dongle_id)
    return dongle_id
Example #15
0
def model_replay(lr, fr, desire=None, calib=None):

    spinner = Spinner()
    spinner.update("starting model replay")

    vipc_server = None
    pm = messaging.PubMaster(
        ['roadCameraState', 'liveCalibration', 'lateralPlan'])
    sm = messaging.SubMaster(['modelV2'])

    # TODO: add dmonitoringmodeld
    try:
        managed_processes['modeld'].start()
        time.sleep(5)
        sm.update(1000)

        desires_by_index = {
            v: k
            for k, v in log.LateralPlan.Desire.schema.enumerants.items()
        }

        cal = [msg for msg in lr if msg.which() == "liveCalibration"]
        for msg in cal[:5]:
            pm.send(msg.which(), replace_calib(msg, calib))

        log_msgs = []
        frame_idx = 0
        for msg in tqdm(lr):
            if msg.which() == "liveCalibration":
                pm.send(msg.which(), replace_calib(msg, calib))
            elif msg.which() == "roadCameraState":
                if desire is not None:
                    for i in desire[frame_idx].nonzero()[0]:
                        dat = messaging.new_message('lateralPlan')
                        dat.lateralPlan.desire = desires_by_index[i]
                        pm.send('lateralPlan', dat)

                f = msg.as_builder()
                pm.send(msg.which(), f)

                img = fr.get(frame_idx, pix_fmt="yuv420p")[0]
                if vipc_server is None:
                    w, h = {
                        int(3 * w * h / 2): (w, h)
                        for (w, h) in [tici_f_frame_size, eon_f_frame_size]
                    }[len(img)]
                    vipc_server = VisionIpcServer("camerad")
                    vipc_server.create_buffers(
                        VisionStreamType.VISION_STREAM_YUV_BACK, 40, False, w,
                        h)
                    vipc_server.start_listener()
                    time.sleep(1)  # wait for modeld to connect

                vipc_server.send(VisionStreamType.VISION_STREAM_YUV_BACK,
                                 img.flatten().tobytes(),
                                 f.roadCameraState.frameId,
                                 f.roadCameraState.timestampSof,
                                 f.roadCameraState.timestampEof)

                with Timeout(seconds=15):
                    log_msgs.append(messaging.recv_one(sm.sock['modelV2']))

                spinner.update("modeld replay %d/%d" %
                               (frame_idx, fr.frame_count))

                frame_idx += 1
                if frame_idx >= fr.frame_count:
                    break
    except KeyboardInterrupt:
        pass
    finally:
        spinner.close()
        managed_processes['modeld'].stop()

    return log_msgs