@ -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