156 lines
3.9 KiB
Python
Executable File
156 lines
3.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import serial
|
|
import sys
|
|
import time
|
|
import os
|
|
import configparser
|
|
config_dump = __import__("modem-config-dump")
|
|
|
|
SERIAL_DEV = '/dev/ttyACM0'
|
|
WWAN_DEV = '/sys/class/net/wwan0'
|
|
SIM_CONFIG = '/etc/sim.conf'
|
|
APN_CONFIG = '/etc/apn.conf'
|
|
GPIO_PATH = '/sys/class/gpio/'
|
|
GPIO_SIM_SW = '44'
|
|
APN_CONFIG = '/etc/apn.conf'
|
|
|
|
def write_to_file(file, value):
|
|
f = open(file, 'w')
|
|
f.write(value)
|
|
f.close()
|
|
|
|
def execute_and_check(ser, cmd):
|
|
tries = 0
|
|
MAX_TRY = 5
|
|
ser.flushInput()
|
|
ser.write(cmd)
|
|
ser.write(b'\r')
|
|
s = ser.read_until(b'OK')
|
|
if b'OK' not in s:
|
|
print("Failed cmd : " + str(cmd))
|
|
print("Output: " + str(s))
|
|
tries += 1
|
|
if tries < MAX_TRY:
|
|
time.sleep(1)
|
|
execute_and_check(ser, cmd)
|
|
else:
|
|
sys.exit(-1)
|
|
tries = 0
|
|
|
|
def switch_sim():
|
|
write_to_file(GPIO_PATH + 'export', GPIO_SIM_SW)
|
|
write_to_file(GPIO_PATH + 'gpio' + GPIO_SIM_SW + '/direction', 'out')
|
|
write_to_file(GPIO_PATH + 'gpio' + GPIO_SIM_SW + '/value', '0')
|
|
|
|
def sim_present(ser):
|
|
cmd = b'AT+CCID?'
|
|
while True:
|
|
try:
|
|
ser.flushInput()
|
|
ser.write(cmd)
|
|
ser.write(b'\r')
|
|
s = ser.read_until(b'OK')
|
|
if b'ERROR' in s:
|
|
return False
|
|
elif b'OK' in s:
|
|
return True
|
|
except Exception as e:
|
|
print("Exception : " + str(e))
|
|
time.sleep(1)
|
|
|
|
return s
|
|
|
|
def check_sim_presence(ser):
|
|
if sim_present(ser):
|
|
print("sim present")
|
|
return False
|
|
else:
|
|
print("no sim, switching to esim")
|
|
switch_sim()
|
|
return True
|
|
|
|
def sim_config(ser):
|
|
config = configparser.ConfigParser()
|
|
config.read(SIM_CONFIG)
|
|
sim = config.get('default', 'SIM')
|
|
print(sim)
|
|
if sim == 'auto':
|
|
return check_sim_presence(ser)
|
|
elif sim == 'esim' or sim == 'ui-top':
|
|
switch_sim()
|
|
return True
|
|
# ui-btm and main are default
|
|
return False
|
|
|
|
def apn_setup(ser):
|
|
if not os.path.exists(APN_CONFIG):
|
|
print('No APN configured')
|
|
return
|
|
|
|
config = configparser.ConfigParser()
|
|
config.read(APN_CONFIG)
|
|
|
|
try:
|
|
apn = config.get('default', 'apn')
|
|
except:
|
|
print('apn.conf malformed : no apn found\n')
|
|
return
|
|
try:
|
|
user = '"' + config.get('default', 'user') + '"'
|
|
try:
|
|
password = '"' + config.get('default', 'password') + '"'
|
|
except:
|
|
print("No password for APN")
|
|
password = 'NULL'
|
|
except:
|
|
print("No user for APN")
|
|
user = 'NULL'
|
|
password = 'NULL'
|
|
|
|
if not apn:
|
|
return
|
|
auth = '1' if user is not 'NULL' else '0'
|
|
print("Switching to airplane mode")
|
|
execute_and_check(ser, b'AT+CFUN=4\r')
|
|
|
|
print("Configuring default ctx")
|
|
cmd = 'AT+UCGDFLT=0,"IP","' + str(apn) + '",0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,' + auth + ',' + str(user) + ',' + str(password) + ',""\r'
|
|
execute_and_check(ser, bytes(cmd, 'utf8'))
|
|
|
|
print("Full functionality mode")
|
|
execute_and_check(ser, b'AT+CFUN=1\r')
|
|
|
|
def main():
|
|
rst = False
|
|
# Wait on device
|
|
while not os.path.exists(SERIAL_DEV):
|
|
time.sleep(1)
|
|
ser = serial.Serial(SERIAL_DEV, 115200, timeout=0.5)
|
|
|
|
if not os.path.exists(WWAN_DEV):
|
|
print("Setting up bridge mode")
|
|
execute_and_check(ser, b'AT+UBMCONF=2')
|
|
|
|
print("Setting up USB mode to ECM")
|
|
execute_and_check(ser, b'AT+UUSBCONF=2,"ECM",0')
|
|
rst = True
|
|
rst = sim_config(ser) or rst
|
|
if rst:
|
|
print("Resetting modem")
|
|
ser.write(b'AT+CFUN=16\r')
|
|
|
|
ser.close()
|
|
while os.path.exists(SERIAL_DEV):
|
|
time.sleep(1)
|
|
while not os.path.exists(SERIAL_DEV):
|
|
time.sleep(1)
|
|
ser = serial.Serial(SERIAL_DEV, 115200, timeout=0.5)
|
|
|
|
apn_setup(ser)
|
|
config_dump.dump_modem_config(ser)
|
|
ser.close()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|