Hardware abstraction class (#2080)

* hardware abstraction class

* De Morgan

* Rename pc hardware class

* Fix sound card in controlsd

* Pc get sim info

* fix hardware in test

* two more

* No more random imei on android

* no randomness on android

* Need to return something that looks like imei for registration to work

* Return proper network strength

* Unused import

* Bug fixes + gpsd is only android
old-commit-hash: c7152d5419
commatwo_master
Willem Melching 5 years ago committed by GitHub
parent 93926b0cd2
commit 16fe1bb2ad
  1. 472
      common/android.py
  2. 10
      common/basedir.py
  3. 50
      common/hardware.py
  4. 34
      common/hardware_base.py
  5. 2
      common/realtime.py
  6. 1
      release/files_common
  7. 20
      selfdrive/athena/athenad.py
  8. 2
      selfdrive/boardd/tests/test_boardd_loopback.py
  9. 4
      selfdrive/controls/controlsd.py
  10. 4
      selfdrive/crash.py
  11. 31
      selfdrive/loggerd/uploader.py
  12. 15
      selfdrive/manager.py
  13. 7
      selfdrive/registration.py
  14. 9
      selfdrive/test/helpers.py
  15. 3
      selfdrive/test/process_replay/camera_replay.py
  16. 4
      selfdrive/test/test_sounds.py
  17. 7
      selfdrive/thermald/thermald.py
  18. 14
      tools/lib/auth_config.py

@ -1,78 +1,32 @@
import os
import binascii import binascii
import itertools import itertools
import os
import re import re
import struct import struct
import subprocess import subprocess
import random
from cereal import log from cereal import log
from common.hardware_base import HardwareBase
NetworkType = log.ThermalData.NetworkType NetworkType = log.ThermalData.NetworkType
NetworkStrength = log.ThermalData.NetworkStrength NetworkStrength = log.ThermalData.NetworkStrength
ANDROID = os.path.isfile('/EON')
def get_sound_card_online():
return (os.path.isfile('/proc/asound/card0/state') and
open('/proc/asound/card0/state').read().strip() == 'ONLINE')
def getprop(key):
if not ANDROID:
return ""
return subprocess.check_output(["getprop", key], encoding='utf8').strip()
def get_imei(slot):
slot = str(slot)
if slot not in ("0", "1"):
raise ValueError("SIM slot must be 0 or 1")
ret = parse_service_call_string(service_call(["iphonesubinfo", "3" , "i32", str(slot)]))
if not ret:
# allow non android to be identified differently
ret = "%015d" % random.randint(0, 1 << 32)
return ret
def get_serial():
ret = getprop("ro.serialno")
if ret == "":
ret = "cccccccc"
return ret
def get_subscriber_info():
ret = parse_service_call_string(service_call(["iphonesubinfo", "7"]))
if ret is None or len(ret) < 8:
return ""
return ret
def reboot(reason=None):
if reason is None:
reason_args = ["null"]
else:
reason_args = ["s16", reason]
subprocess.check_output([
"service", "call", "power", "16", # IPowerManager.reboot
"i32", "0", # no confirmation,
*reason_args,
"i32", "1" # wait
])
def service_call(call): def service_call(call):
if not ANDROID:
return None
ret = subprocess.check_output(["service", "call", *call], encoding='utf8').strip() ret = subprocess.check_output(["service", "call", *call], encoding='utf8').strip()
if 'Parcel' not in ret: if 'Parcel' not in ret:
return None return None
return parse_service_call_bytes(ret) return parse_service_call_bytes(ret)
def parse_service_call_unpack(r, fmt): def parse_service_call_unpack(r, fmt):
try: try:
return struct.unpack(fmt, r)[0] return struct.unpack(fmt, r)[0]
except Exception: except Exception:
return None return None
def parse_service_call_string(r): def parse_service_call_string(r):
try: try:
r = r[8:] # Cut off length field r = r[8:] # Cut off length field
@ -89,6 +43,7 @@ def parse_service_call_string(r):
except Exception: except Exception:
return None return None
def parse_service_call_bytes(ret): def parse_service_call_bytes(ret):
try: try:
r = b"" r = b""
@ -98,189 +53,248 @@ def parse_service_call_bytes(ret):
except Exception: except Exception:
return None return None
def get_network_type():
if not ANDROID: def getprop(key):
return NetworkType.none return subprocess.check_output(["getprop", key], encoding='utf8').strip()
wifi_check = parse_service_call_string(service_call(["connectivity", "2"]))
if wifi_check is None: class Android(HardwareBase):
return NetworkType.none def get_sound_card_online(self):
elif 'WIFI' in wifi_check: return (os.path.isfile('/proc/asound/card0/state') and
return NetworkType.wifi open('/proc/asound/card0/state').read().strip() == 'ONLINE')
else:
cell_check = parse_service_call_unpack(service_call(['phone', '59']), ">q") def get_imei(self, slot):
# from TelephonyManager.java slot = str(slot)
cell_networks = { if slot not in ("0", "1"):
0: NetworkType.none, raise ValueError("SIM slot must be 0 or 1")
1: NetworkType.cell2G,
2: NetworkType.cell2G, return parse_service_call_string(service_call(["iphonesubinfo", "3", "i32", str(slot)]))
3: NetworkType.cell3G,
4: NetworkType.cell2G, def get_serial(self):
5: NetworkType.cell3G, ret = getprop("ro.serialno")
6: NetworkType.cell3G, if ret == "":
7: NetworkType.cell3G, ret = "cccccccc"
8: NetworkType.cell3G, return ret
9: NetworkType.cell3G,
10: NetworkType.cell3G, def get_subscriber_info(self):
11: NetworkType.cell2G, ret = parse_service_call_string(service_call(["iphonesubinfo", "7"]))
12: NetworkType.cell3G, if ret is None or len(ret) < 8:
13: NetworkType.cell4G, return ""
14: NetworkType.cell4G, return ret
15: NetworkType.cell3G,
16: NetworkType.cell2G, def reboot(self, reason=None):
17: NetworkType.cell3G, # e.g. reason="recovery" to go into recover mode
18: NetworkType.cell4G, if reason is None:
19: NetworkType.cell4G reason_args = ["null"]
}
return cell_networks.get(cell_check, NetworkType.none)
def get_network_strength(network_type):
network_strength = NetworkStrength.unknown
# from SignalStrength.java
def get_lte_level(rsrp, rssnr):
INT_MAX = 2147483647
if rsrp == INT_MAX:
lvl_rsrp = NetworkStrength.unknown
elif rsrp >= -95:
lvl_rsrp = NetworkStrength.great
elif rsrp >= -105:
lvl_rsrp = NetworkStrength.good
elif rsrp >= -115:
lvl_rsrp = NetworkStrength.moderate
else: else:
lvl_rsrp = NetworkStrength.poor reason_args = ["s16", reason]
if rssnr == INT_MAX:
lvl_rssnr = NetworkStrength.unknown subprocess.check_output([
elif rssnr >= 45: "service", "call", "power", "16", # IPowerManager.reboot
lvl_rssnr = NetworkStrength.great "i32", "0", # no confirmation,
elif rssnr >= 10: *reason_args,
lvl_rssnr = NetworkStrength.good "i32", "1" # wait
elif rssnr >= -30: ])
lvl_rssnr = NetworkStrength.moderate
def get_sim_info(self):
# Used for athena
# TODO: build using methods from this class
sim_state = getprop("gsm.sim.state").split(",")
network_type = getprop("gsm.network.type").split(',')
mcc_mnc = getprop("gsm.sim.operator.numeric") or None
sim_id = parse_service_call_string(service_call(['iphonesubinfo', '11']))
cell_data_state = parse_service_call_unpack(service_call(['phone', '46']), ">q")
cell_data_connected = (cell_data_state == 2)
return {
'sim_id': sim_id,
'mcc_mnc': mcc_mnc,
'network_type': network_type,
'sim_state': sim_state,
'data_connected': cell_data_connected
}
def get_network_type(self):
wifi_check = parse_service_call_string(service_call(["connectivity", "2"]))
if wifi_check is None:
return NetworkType.none
elif 'WIFI' in wifi_check:
return NetworkType.wifi
else: else:
lvl_rssnr = NetworkStrength.poor cell_check = parse_service_call_unpack(service_call(['phone', '59']), ">q")
return max(lvl_rsrp, lvl_rssnr) # from TelephonyManager.java
cell_networks = {
0: NetworkType.none,
1: NetworkType.cell2G,
2: NetworkType.cell2G,
3: NetworkType.cell3G,
4: NetworkType.cell2G,
5: NetworkType.cell3G,
6: NetworkType.cell3G,
7: NetworkType.cell3G,
8: NetworkType.cell3G,
9: NetworkType.cell3G,
10: NetworkType.cell3G,
11: NetworkType.cell2G,
12: NetworkType.cell3G,
13: NetworkType.cell4G,
14: NetworkType.cell4G,
15: NetworkType.cell3G,
16: NetworkType.cell2G,
17: NetworkType.cell3G,
18: NetworkType.cell4G,
19: NetworkType.cell4G
}
return cell_networks.get(cell_check, NetworkType.none)
def get_tdscdma_level(tdscmadbm): def get_network_strength(self, network_type):
lvl = NetworkStrength.unknown network_strength = NetworkStrength.unknown
if tdscmadbm > -25:
lvl = NetworkStrength.unknown # from SignalStrength.java
elif tdscmadbm >= -49: def get_lte_level(rsrp, rssnr):
lvl = NetworkStrength.great INT_MAX = 2147483647
elif tdscmadbm >= -73: if rsrp == INT_MAX:
lvl = NetworkStrength.good lvl_rsrp = NetworkStrength.unknown
elif tdscmadbm >= -97: elif rsrp >= -95:
lvl = NetworkStrength.moderate lvl_rsrp = NetworkStrength.great
elif tdscmadbm >= -110: elif rsrp >= -105:
lvl = NetworkStrength.poor lvl_rsrp = NetworkStrength.good
return lvl elif rsrp >= -115:
lvl_rsrp = NetworkStrength.moderate
def get_gsm_level(asu): else:
if asu <= 2 or asu == 99: lvl_rsrp = NetworkStrength.poor
if rssnr == INT_MAX:
lvl_rssnr = NetworkStrength.unknown
elif rssnr >= 45:
lvl_rssnr = NetworkStrength.great
elif rssnr >= 10:
lvl_rssnr = NetworkStrength.good
elif rssnr >= -30:
lvl_rssnr = NetworkStrength.moderate
else:
lvl_rssnr = NetworkStrength.poor
return max(lvl_rsrp, lvl_rssnr)
def get_tdscdma_level(tdscmadbm):
lvl = NetworkStrength.unknown lvl = NetworkStrength.unknown
elif asu >= 12: if tdscmadbm > -25:
lvl = NetworkStrength.great lvl = NetworkStrength.unknown
elif asu >= 8: elif tdscmadbm >= -49:
lvl = NetworkStrength.good lvl = NetworkStrength.great
elif asu >= 5: elif tdscmadbm >= -73:
lvl = NetworkStrength.moderate lvl = NetworkStrength.good
elif tdscmadbm >= -97:
lvl = NetworkStrength.moderate
elif tdscmadbm >= -110:
lvl = NetworkStrength.poor
return lvl
def get_gsm_level(asu):
if asu <= 2 or asu == 99:
lvl = NetworkStrength.unknown
elif asu >= 12:
lvl = NetworkStrength.great
elif asu >= 8:
lvl = NetworkStrength.good
elif asu >= 5:
lvl = NetworkStrength.moderate
else:
lvl = NetworkStrength.poor
return lvl
def get_evdo_level(evdodbm, evdosnr):
lvl_evdodbm = NetworkStrength.unknown
lvl_evdosnr = NetworkStrength.unknown
if evdodbm >= -65:
lvl_evdodbm = NetworkStrength.great
elif evdodbm >= -75:
lvl_evdodbm = NetworkStrength.good
elif evdodbm >= -90:
lvl_evdodbm = NetworkStrength.moderate
elif evdodbm >= -105:
lvl_evdodbm = NetworkStrength.poor
if evdosnr >= 7:
lvl_evdosnr = NetworkStrength.great
elif evdosnr >= 5:
lvl_evdosnr = NetworkStrength.good
elif evdosnr >= 3:
lvl_evdosnr = NetworkStrength.moderate
elif evdosnr >= 1:
lvl_evdosnr = NetworkStrength.poor
return max(lvl_evdodbm, lvl_evdosnr)
def get_cdma_level(cdmadbm, cdmaecio):
lvl_cdmadbm = NetworkStrength.unknown
lvl_cdmaecio = NetworkStrength.unknown
if cdmadbm >= -75:
lvl_cdmadbm = NetworkStrength.great
elif cdmadbm >= -85:
lvl_cdmadbm = NetworkStrength.good
elif cdmadbm >= -95:
lvl_cdmadbm = NetworkStrength.moderate
elif cdmadbm >= -100:
lvl_cdmadbm = NetworkStrength.poor
if cdmaecio >= -90:
lvl_cdmaecio = NetworkStrength.great
elif cdmaecio >= -110:
lvl_cdmaecio = NetworkStrength.good
elif cdmaecio >= -130:
lvl_cdmaecio = NetworkStrength.moderate
elif cdmaecio >= -150:
lvl_cdmaecio = NetworkStrength.poor
return max(lvl_cdmadbm, lvl_cdmaecio)
if network_type == NetworkType.none:
return network_strength
if network_type == NetworkType.wifi:
out = subprocess.check_output('dumpsys connectivity', shell=True).decode('utf-8')
network_strength = NetworkStrength.unknown
for line in out.split('\n'):
signal_str = "SignalStrength: "
if signal_str in line:
lvl_idx_start = line.find(signal_str) + len(signal_str)
lvl_idx_end = line.find(']', lvl_idx_start)
lvl = int(line[lvl_idx_start : lvl_idx_end])
if lvl >= -50:
network_strength = NetworkStrength.great
elif lvl >= -60:
network_strength = NetworkStrength.good
elif lvl >= -70:
network_strength = NetworkStrength.moderate
else:
network_strength = NetworkStrength.poor
return network_strength
else: else:
lvl = NetworkStrength.poor # check cell strength
return lvl out = subprocess.check_output('dumpsys telephony.registry', shell=True).decode('utf-8')
for line in out.split('\n'):
def get_evdo_level(evdodbm, evdosnr): if "mSignalStrength" in line:
lvl_evdodbm = NetworkStrength.unknown arr = line.split(' ')
lvl_evdosnr = NetworkStrength.unknown ns = 0
if evdodbm >= -65: if ("gsm" in arr[14]):
lvl_evdodbm = NetworkStrength.great rsrp = int(arr[9])
elif evdodbm >= -75: rssnr = int(arr[11])
lvl_evdodbm = NetworkStrength.good ns = get_lte_level(rsrp, rssnr)
elif evdodbm >= -90:
lvl_evdodbm = NetworkStrength.moderate
elif evdodbm >= -105:
lvl_evdodbm = NetworkStrength.poor
if evdosnr >= 7:
lvl_evdosnr = NetworkStrength.great
elif evdosnr >= 5:
lvl_evdosnr = NetworkStrength.good
elif evdosnr >= 3:
lvl_evdosnr = NetworkStrength.moderate
elif evdosnr >= 1:
lvl_evdosnr = NetworkStrength.poor
return max(lvl_evdodbm, lvl_evdosnr)
def get_cdma_level(cdmadbm, cdmaecio):
lvl_cdmadbm = NetworkStrength.unknown
lvl_cdmaecio = NetworkStrength.unknown
if cdmadbm >= -75:
lvl_cdmadbm = NetworkStrength.great
elif cdmadbm >= -85:
lvl_cdmadbm = NetworkStrength.good
elif cdmadbm >= -95:
lvl_cdmadbm = NetworkStrength.moderate
elif cdmadbm >= -100:
lvl_cdmadbm = NetworkStrength.poor
if cdmaecio >= -90:
lvl_cdmaecio = NetworkStrength.great
elif cdmaecio >= -110:
lvl_cdmaecio = NetworkStrength.good
elif cdmaecio >= -130:
lvl_cdmaecio = NetworkStrength.moderate
elif cdmaecio >= -150:
lvl_cdmaecio = NetworkStrength.poor
return max(lvl_cdmadbm, lvl_cdmaecio)
if network_type == NetworkType.none:
return network_strength
if network_type == NetworkType.wifi:
out = subprocess.check_output('dumpsys connectivity', shell=True).decode('utf-8')
network_strength = NetworkStrength.unknown
for line in out.split('\n'):
signal_str = "SignalStrength: "
if signal_str in line:
lvl_idx_start = line.find(signal_str) + len(signal_str)
lvl_idx_end = line.find(']', lvl_idx_start)
lvl = int(line[lvl_idx_start : lvl_idx_end])
if lvl >= -50:
network_strength = NetworkStrength.great
elif lvl >= -60:
network_strength = NetworkStrength.good
elif lvl >= -70:
network_strength = NetworkStrength.moderate
else:
network_strength = NetworkStrength.poor
return network_strength
else:
# check cell strength
out = subprocess.check_output('dumpsys telephony.registry', shell=True).decode('utf-8')
for line in out.split('\n'):
if "mSignalStrength" in line:
arr = line.split(' ')
ns = 0
if ("gsm" in arr[14]):
rsrp = int(arr[9])
rssnr = int(arr[11])
ns = get_lte_level(rsrp, rssnr)
if ns == NetworkStrength.unknown:
tdscmadbm = int(arr[13])
ns = get_tdscdma_level(tdscmadbm)
if ns == NetworkStrength.unknown: if ns == NetworkStrength.unknown:
asu = int(arr[1]) tdscmadbm = int(arr[13])
ns = get_gsm_level(asu) ns = get_tdscdma_level(tdscmadbm)
else: if ns == NetworkStrength.unknown:
cdmadbm = int(arr[3]) asu = int(arr[1])
cdmaecio = int(arr[4]) ns = get_gsm_level(asu)
evdodbm = int(arr[5])
evdosnr = int(arr[7])
lvl_cdma = get_cdma_level(cdmadbm, cdmaecio)
lvl_edmo = get_evdo_level(evdodbm, evdosnr)
if lvl_edmo == NetworkStrength.unknown:
ns = lvl_cdma
elif lvl_cdma == NetworkStrength.unknown:
ns = lvl_edmo
else: else:
ns = min(lvl_cdma, lvl_edmo) cdmadbm = int(arr[3])
network_strength = max(network_strength, ns) cdmaecio = int(arr[4])
evdodbm = int(arr[5])
evdosnr = int(arr[7])
lvl_cdma = get_cdma_level(cdmadbm, cdmaecio)
lvl_edmo = get_evdo_level(evdodbm, evdosnr)
if lvl_edmo == NetworkStrength.unknown:
ns = lvl_cdma
elif lvl_cdma == NetworkStrength.unknown:
ns = lvl_edmo
else:
ns = min(lvl_cdma, lvl_edmo)
network_strength = max(network_strength, ns)
return network_strength return network_strength

@ -1,10 +1,10 @@
import os import os
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")) BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../"))
from common.android import ANDROID from common.hardware import PC
if ANDROID: if PC:
PERSIST = "/persist"
PARAMS = "/data/params"
else:
PERSIST = os.path.join(BASEDIR, "persist") PERSIST = os.path.join(BASEDIR, "persist")
PARAMS = os.path.join(BASEDIR, "persist", "params") PARAMS = os.path.join(BASEDIR, "persist", "params")
else:
PERSIST = "/persist"
PARAMS = "/data/params"

@ -1,4 +1,54 @@
import os import os
import random
from typing import cast
from cereal import log
from common.android import Android
from common.hardware_base import HardwareBase
EON = os.path.isfile('/EON') EON = os.path.isfile('/EON')
TICI = os.path.isfile('/TICI') TICI = os.path.isfile('/TICI')
PC = not (EON or TICI)
ANDROID = EON
NetworkType = log.ThermalData.NetworkType
NetworkStrength = log.ThermalData.NetworkStrength
class Pc(HardwareBase):
def get_sound_card_online(self):
return True
def get_imei(self, slot):
return "%015d" % random.randint(0, 1 << 32)
def get_serial(self):
return "cccccccc"
def get_subscriber_info(self):
return ""
def reboot(self, reason=None):
print("REBOOT!")
def get_network_type(self):
return NetworkType.none
def get_sim_info(self):
return {
'sim_id': '',
'mcc_mnc': None,
'network_type': ["Unknown"],
'sim_state': ["ABSENT"],
'data_connected': False
}
def get_network_strength(self, network_type):
return NetworkStrength.unknown
if EON:
HARDWARE = cast(HardwareBase, Android())
else:
HARDWARE = cast(HardwareBase, Pc())

@ -0,0 +1,34 @@
from abc import abstractmethod
class HardwareBase:
@abstractmethod
def get_sound_card_online(self):
pass
@abstractmethod
def get_imei(self, slot):
pass
@abstractmethod
def get_serial(self):
pass
@abstractmethod
def get_subscriber_info(self):
pass
@abstractmethod
def reboot(self, reason=None):
pass
@abstractmethod
def get_network_type(self):
pass
@abstractmethod
def get_sim_info(self):
pass
@abstractmethod
def get_network_strength(self, network_type):
pass

@ -6,7 +6,7 @@ import subprocess
import multiprocessing import multiprocessing
from cffi import FFI from cffi import FFI
from common.android import ANDROID from common.hardware import ANDROID
from common.common_pyx import sec_since_boot # pylint: disable=no-name-in-module, import-error from common.common_pyx import sec_since_boot # pylint: disable=no-name-in-module, import-error

@ -19,6 +19,7 @@ common/.gitignore
common/__init__.py common/__init__.py
common/android.py common/android.py
common/hardware.py common/hardware.py
common/hardware_base.py
common/gpio.py common/gpio.py
common/realtime.py common/realtime.py
common/clock.pyx common/clock.pyx

@ -20,7 +20,7 @@ from websocket import ABNF, WebSocketTimeoutException, create_connection
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal.services import service_list from cereal.services import service_list
from common import android from common.hardware import HARDWARE
from common.api import Api from common.api import Api
from common.basedir import PERSIST from common.basedir import PERSIST
from common.params import Params from common.params import Params
@ -132,7 +132,7 @@ def reboot():
def do_reboot(): def do_reboot():
time.sleep(2) time.sleep(2)
android.reboot() HARDWARE.reboot()
threading.Thread(target=do_reboot).start() threading.Thread(target=do_reboot).start()
@ -218,21 +218,7 @@ def getSshAuthorizedKeys():
@dispatcher.add_method @dispatcher.add_method
def getSimInfo(): def getSimInfo():
sim_state = android.getprop("gsm.sim.state").split(",") return HARDWARE.get_sim_info()
network_type = android.getprop("gsm.network.type").split(',')
mcc_mnc = android.getprop("gsm.sim.operator.numeric") or None
sim_id = android.parse_service_call_string(android.service_call(['iphonesubinfo', '11']))
cell_data_state = android.parse_service_call_unpack(android.service_call(['phone', '46']), ">q")
cell_data_connected = (cell_data_state == 2)
return {
'sim_id': sim_id,
'mcc_mnc': mcc_mnc,
'network_type': network_type,
'sim_state': sim_state,
'data_connected': cell_data_connected
}
@dispatcher.add_method @dispatcher.add_method

@ -8,7 +8,7 @@ from functools import wraps
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal import car from cereal import car
from common.basedir import PARAMS from common.basedir import PARAMS
from common.android import ANDROID from common.hardware import ANDROID
from common.params import Params from common.params import Params
from common.spinner import Spinner from common.spinner import Spinner
from panda import Panda from panda import Panda

@ -2,7 +2,7 @@
import os import os
import gc import gc
from cereal import car, log from cereal import car, log
from common.android import ANDROID, get_sound_card_online from common.hardware import HARDWARE
from common.numpy_fast import clip from common.numpy_fast import clip
from common.realtime import sec_since_boot, set_realtime_priority, set_core_affinity, Ratekeeper, DT_CTRL from common.realtime import sec_since_boot, set_realtime_priority, set_core_affinity, Ratekeeper, DT_CTRL
from common.profiler import Profiler from common.profiler import Profiler
@ -79,7 +79,7 @@ class Controls:
internet_needed or not openpilot_enabled_toggle internet_needed or not openpilot_enabled_toggle
# detect sound card presence and ensure successful init # detect sound card presence and ensure successful init
sounds_available = not ANDROID or get_sound_card_online() sounds_available = HARDWARE.get_sound_card_online()
car_recognized = self.CP.carName != 'mock' car_recognized = self.CP.carName != 'mock'
# If stock camera is disconnected, we loaded car controls and it's not dashcam mode # If stock camera is disconnected, we loaded car controls and it's not dashcam mode

@ -6,9 +6,9 @@ import capnp
from selfdrive.version import version, dirty from selfdrive.version import version, dirty
from selfdrive.swaglog import cloudlog from selfdrive.swaglog import cloudlog
from common.android import ANDROID from common.hardware import PC
if os.getenv("NOLOG") or os.getenv("NOCRASH") or not ANDROID: if os.getenv("NOLOG") or os.getenv("NOCRASH") or PC:
def capture_exception(*args, **kwargs): def capture_exception(*args, **kwargs):
pass pass

@ -1,24 +1,26 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import ctypes
import inspect
import json
import os import os
import random
import re import re
import subprocess
import threading
import time import time
import json
import random
import ctypes
import inspect
import requests
import traceback import traceback
import threading
import subprocess
from selfdrive.swaglog import cloudlog import requests
from selfdrive.loggerd.config import ROOT
from common import android from cereal import log
from common.params import Params from common.hardware import HARDWARE
from common.api import Api from common.api import Api
from common.params import Params
from common.xattr import getxattr, setxattr from common.xattr import getxattr, setxattr
from selfdrive.loggerd.config import ROOT
from selfdrive.swaglog import cloudlog
NetworkType = log.ThermalData.NetworkType
UPLOAD_ATTR_NAME = 'user.upload' UPLOAD_ATTR_NAME = 'user.upload'
UPLOAD_ATTR_VALUE = b'1' UPLOAD_ATTR_VALUE = b'1'
@ -69,13 +71,8 @@ def clear_locks(root):
cloudlog.exception("clear_locks failed") cloudlog.exception("clear_locks failed")
def is_on_wifi(): def is_on_wifi():
# ConnectivityManager.getActiveNetworkInfo()
try: try:
# TODO: figure out why the android service call sometimes dies with SIGUSR2 (signal from MSGQ) return HARDWARE.get_network_type() == NetworkType.wifi
result = android.parse_service_call_string(android.service_call(["connectivity", "2"]))
if result is None:
return True
return 'WIFI' in result
except Exception: except Exception:
cloudlog.exception("is_on_wifi failed") cloudlog.exception("is_on_wifi failed")
return False return False

@ -14,7 +14,7 @@ from selfdrive.swaglog import cloudlog, add_logentries_handler
from common.basedir import BASEDIR, PARAMS from common.basedir import BASEDIR, PARAMS
from common.android import ANDROID from common.hardware import HARDWARE, ANDROID, PC
WEBCAM = os.getenv("WEBCAM") is not None WEBCAM = os.getenv("WEBCAM") is not None
sys.path.append(os.path.join(BASEDIR, "pyextra")) sys.path.append(os.path.join(BASEDIR, "pyextra"))
os.environ['BASEDIR'] = BASEDIR os.environ['BASEDIR'] = BASEDIR
@ -156,7 +156,6 @@ from selfdrive.registration import register
from selfdrive.version import version, dirty from selfdrive.version import version, dirty
from selfdrive.loggerd.config import ROOT from selfdrive.loggerd.config import ROOT
from selfdrive.launcher import launcher from selfdrive.launcher import launcher
from common import android
from common.apk import update_apks, pm_apply_packages, start_offroad from common.apk import update_apks, pm_apply_packages, start_offroad
ThermalStatus = cereal.log.ThermalData.ThermalStatus ThermalStatus = cereal.log.ThermalData.ThermalStatus
@ -253,13 +252,18 @@ if WEBCAM:
'dmonitoringmodeld', 'dmonitoringmodeld',
] ]
if ANDROID: if not PC:
car_started_processes += [ car_started_processes += [
'sensord', 'sensord',
'gpsd',
'dmonitoringmodeld', 'dmonitoringmodeld',
] ]
if ANDROID:
car_started_processes += [
'gpsd',
]
def register_managed_process(name, desc, car_started=False): def register_managed_process(name, desc, car_started=False):
global managed_processes, car_started_processes, persistent_processes global managed_processes, car_started_processes, persistent_processes
print("registering %s" % name) print("registering %s" % name)
@ -365,6 +369,7 @@ def kill_managed_process(name):
join_process(running[name], 15) join_process(running[name], 15)
if running[name].exitcode is None: if running[name].exitcode is None:
cloudlog.critical("unkillable process %s failed to die!" % name) cloudlog.critical("unkillable process %s failed to die!" % name)
# TODO: Use method from HARDWARE
if ANDROID: if ANDROID:
cloudlog.critical("FORCE REBOOTING PHONE!") cloudlog.critical("FORCE REBOOTING PHONE!")
os.system("date >> /sdcard/unkillable_reboot") os.system("date >> /sdcard/unkillable_reboot")
@ -536,7 +541,7 @@ def uninstall():
with open('/cache/recovery/command', 'w') as f: with open('/cache/recovery/command', 'w') as f:
f.write('--wipe_data\n') f.write('--wipe_data\n')
# IPowerManager.reboot(confirm=false, reason="recovery", wait=true) # IPowerManager.reboot(confirm=false, reason="recovery", wait=true)
android.reboot(reason="recovery") HARDWARE.reboot(reason="recovery")
def main(): def main():
os.environ['PARAMS_PATH'] = PARAMS os.environ['PARAMS_PATH'] = PARAMS

@ -4,12 +4,13 @@ import json
from datetime import datetime, timedelta from datetime import datetime, timedelta
from selfdrive.swaglog import cloudlog from selfdrive.swaglog import cloudlog
from selfdrive.version import version, terms_version, training_version, get_git_commit, get_git_branch, get_git_remote from selfdrive.version import version, terms_version, training_version, get_git_commit, get_git_branch, get_git_remote
from common.android import get_imei, get_serial, get_subscriber_info from common.hardware import HARDWARE
from common.api import api_get from common.api import api_get
from common.params import Params from common.params import Params
from common.file_helpers import mkdirs_exists_ok from common.file_helpers import mkdirs_exists_ok
from common.basedir import PERSIST from common.basedir import PERSIST
def register(): def register():
params = Params() params = Params()
params.put("Version", version) params.put("Version", version)
@ -19,7 +20,7 @@ def register():
params.put("GitCommit", get_git_commit(default="")) params.put("GitCommit", get_git_commit(default=""))
params.put("GitBranch", get_git_branch(default="")) params.put("GitBranch", get_git_branch(default=""))
params.put("GitRemote", get_git_remote(default="")) params.put("GitRemote", get_git_remote(default=""))
params.put("SubscriberInfo", get_subscriber_info()) params.put("SubscriberInfo", HARDWARE.get_subscriber_info())
# create a key for auth # create a key for auth
# your private key is kept on your device persist partition and never sent to our servers # your private key is kept on your device persist partition and never sent to our servers
@ -50,7 +51,7 @@ def register():
try: try:
cloudlog.info("getting pilotauth") cloudlog.info("getting pilotauth")
resp = api_get("v2/pilotauth/", method='POST', timeout=15, resp = api_get("v2/pilotauth/", method='POST', timeout=15,
imei=get_imei(0), imei2=get_imei(1), serial=get_serial(), public_key=public_key, register_token=register_token) imei=HARDWARE.get_imei(0), imei2=HARDWARE.get_imei(1), serial=HARDWARE.get_serial(), public_key=public_key, register_token=register_token)
dongleauth = json.loads(resp.text) dongleauth = json.loads(resp.text)
dongle_id = dongleauth["dongle_id"] dongle_id = dongleauth["dongle_id"]

@ -3,7 +3,7 @@ import subprocess
from functools import wraps from functools import wraps
from nose.tools import nottest from nose.tools import nottest
from common.android import ANDROID from common.hardware import PC
from common.apk import update_apks, start_offroad, pm_apply_packages, android_packages from common.apk import update_apks, start_offroad, pm_apply_packages, android_packages
from common.params import Params from common.params import Params
from selfdrive.version import training_version, terms_version from selfdrive.version import training_version, terms_version
@ -19,10 +19,10 @@ def set_params_enabled():
params.put("CompletedTrainingVersion", training_version) params.put("CompletedTrainingVersion", training_version)
def phone_only(x): def phone_only(x):
if ANDROID: if PC:
return x
else:
return nottest(x) return nottest(x)
else:
return x
def with_processes(processes, init_time=0): def with_processes(processes, init_time=0):
def wrapper(func): def wrapper(func):
@ -68,4 +68,3 @@ def with_apks():
assert apk_is_not_running, package assert apk_is_not_running, package
return wrap return wrap
return wrapper return wrapper

@ -5,7 +5,7 @@ import time
from typing import Any from typing import Any
from tqdm import tqdm from tqdm import tqdm
from common.android import ANDROID from common.hardware import ANDROID
os.environ['CI'] = "1" os.environ['CI'] = "1"
if ANDROID: if ANDROID:
os.environ['QCOM_REPLAY'] = "1" os.environ['QCOM_REPLAY'] = "1"
@ -101,4 +101,3 @@ if __name__ == "__main__":
f.write(diff2) f.write(diff2)
sys.exit(int(failed)) sys.exit(int(failed))

@ -5,7 +5,7 @@ import subprocess
from cereal import log, car from cereal import log, car
import cereal.messaging as messaging import cereal.messaging as messaging
from selfdrive.test.helpers import phone_only, with_processes from selfdrive.test.helpers import phone_only, with_processes
from common.android import get_sound_card_online from common.hardware import HARDWARE
from common.realtime import DT_CTRL from common.realtime import DT_CTRL
AudibleAlert = car.CarControl.HUDControl.AudibleAlert AudibleAlert = car.CarControl.HUDControl.AudibleAlert
@ -30,7 +30,7 @@ def get_total_writes():
@phone_only @phone_only
def test_sound_card_init(): def test_sound_card_init():
assert get_sound_card_online() assert HARDWARE.get_sound_card_online()
@phone_only @phone_only

@ -9,9 +9,8 @@ from smbus2 import SMBus
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal import log from cereal import log
from common.android import get_network_strength, get_network_type
from common.filter_simple import FirstOrderFilter from common.filter_simple import FirstOrderFilter
from common.hardware import EON, TICI from common.hardware import EON, HARDWARE, TICI
from common.numpy_fast import clip, interp from common.numpy_fast import clip, interp
from common.params import Params, put_nonblocking from common.params import Params, put_nonblocking
from common.realtime import DT_TRML, sec_since_boot from common.realtime import DT_TRML, sec_since_boot
@ -241,8 +240,8 @@ def thermald_thread():
# get_network_type is an expensive call. update every 10s # get_network_type is an expensive call. update every 10s
if (count % int(10. / DT_TRML)) == 0: if (count % int(10. / DT_TRML)) == 0:
try: try:
network_type = get_network_type() network_type = HARDWARE.get_network_type()
network_strength = get_network_strength(network_type) network_strength = HARDWARE.get_network_strength(network_type)
except Exception: except Exception:
cloudlog.exception("Error getting network status") cloudlog.exception("Error getting network status")

@ -1,17 +1,21 @@
import json import json
import os import os
from common.android import ANDROID from common.hardware import PC
from common.file_helpers import mkdirs_exists_ok from common.file_helpers import mkdirs_exists_ok
class MissingAuthConfigError(Exception): class MissingAuthConfigError(Exception):
pass pass
if ANDROID:
CONFIG_DIR = "/tmp/.comma" if PC:
else:
CONFIG_DIR = os.path.expanduser('~/.comma') CONFIG_DIR = os.path.expanduser('~/.comma')
else:
CONFIG_DIR = "/tmp/.comma"
mkdirs_exists_ok(CONFIG_DIR) mkdirs_exists_ok(CONFIG_DIR)
def get_token(): def get_token():
try: try:
with open(os.path.join(CONFIG_DIR, 'auth.json')) as f: with open(os.path.join(CONFIG_DIR, 'auth.json')) as f:
@ -20,9 +24,11 @@ def get_token():
except Exception: except Exception:
raise MissingAuthConfigError('Authenticate with tools/lib/auth.py') raise MissingAuthConfigError('Authenticate with tools/lib/auth.py')
def set_token(token): def set_token(token):
with open(os.path.join(CONFIG_DIR, 'auth.json'), 'w') as f: with open(os.path.join(CONFIG_DIR, 'auth.json'), 'w') as f:
json.dump({'access_token': token}, f) json.dump({'access_token': token}, f)
def clear_token(): def clear_token():
os.unlink(os.path.join(CONFIG_DIR, 'auth.json')) os.unlink(os.path.join(CONFIG_DIR, 'auth.json'))

Loading…
Cancel
Save