diff --git a/recipes-connectivity/modem-config-dump/files/modem-config-dump.py b/recipes-connectivity/modem-config-dump/files/modem-config-dump.py deleted file mode 100755 index f543be7..0000000 --- a/recipes-connectivity/modem-config-dump/files/modem-config-dump.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 - -import serial -import os -import time -import re - - -CONF_PATH = '/run/modem' -ser = serial.Serial('/dev/ttyACM0', 115200, timeout=0.5) -while True: - try: - ser.read() - break - except Exception: - pass - - -os.makedirs(CONF_PATH, exist_ok=True) -config_full_file = open(CONF_PATH + '/modem-at.config', 'w') -config_file = open(CONF_PATH + '/modem.config', 'w') - - -def usb_profile_parser(output): - x = re.search('UUSBCONF:\s\d,"(.*)",', output) - return x.group(1) - -def mode_parser(output): - x = re.search('UBMCONF:\s(\d)', output) - mode = int(x.group(1)) - if mode == 1: - return "Router" - elif mode == 2: - return "Bridge" - else: - return "unsupported" - -def apn_parser(output): - x = re.search('","(.*)",', output) - return x.group(1) - -def default_parser(output): - x = re.search('(.*)\n.*\nOK',output) - return x.group(1) - -def read_config(cmd, label='', parser=default_parser): - while True: - try: - ser.flushInput() - ser.write(cmd) - ser.write(b'\r') - s = ser.read_until(b'OK') - if(len(s.decode('utf-8')) < 4): # Avoid empty response just after reset - continue - break - except Exception as e: - print("Exception : " + str(e)) - time.sleep(1) - continue - - config_full_file.write(label + '\n') - config_full_file.write(s.decode('utf-8').strip("OK")) - - config_file.write((label + ':').ljust(20)) - config_file.write(parser(s.decode('utf-8')) + '\n') - -read_config(b'AT+CGMI', 'VendorID') -read_config(b'AT+CGMM', 'ModelID') -read_config(b'AT+CGMR', 'Firmware') - -config_full_file.write('-' * 80 + '\n' * 2) - -read_config(b'AT+UCGDFLT?', 'Default APN', apn_parser) -read_config(b'AT+UBMCONF?', 'Mode', mode_parser) -read_config(b'AT+UUSBCONF?', 'USBprofile', usb_profile_parser) - diff --git a/recipes-connectivity/modem-config-dump/files/modem-config-dump.service b/recipes-connectivity/modem-config-dump/files/modem-config-dump.service deleted file mode 100644 index f07ced9..0000000 --- a/recipes-connectivity/modem-config-dump/files/modem-config-dump.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Before=ModemManager.service -After=sim-config.service - -[Service] -Type=oneshot -ExecStart=/usr/bin/modem-config-dump - -[Install] -WantedBy=ModemManager.service - - diff --git a/recipes-connectivity/modem-config-dump/modem-config-dump.bb b/recipes-connectivity/modem-config-dump/modem-config-dump.bb deleted file mode 100644 index 20b2888..0000000 --- a/recipes-connectivity/modem-config-dump/modem-config-dump.bb +++ /dev/null @@ -1,38 +0,0 @@ -SUMMARY = "Dump of the modem config" -DESCRIPTION = "Dump the config of the modem for debugging purposes" -AUTHOR = "Alexandre Bard" - -SECTION = "connectivity" -LICENSE = "GPLv2+" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" -PR = "r2" - -RDEPENDS_${PN}="python3-pyserial" - -inherit systemd - -SRC_URI = " \ - file://modem-config-dump.service \ - file://modem-config-dump.py \ - " - -S = "${WORKDIR}" - -INHIBIT_PACKAGE_DEBUG_SPLIT = "1" - -SYSTEMD_SERVICE_${PN} = "modem-config-dump.service" -SYSTEMD_AUTO_ENABLE ?= "enable" - -FILES_${PN}_append = " \ - /lib \ - /usr \ - " - -do_install () { - install -d ${D}${systemd_unitdir}/system/ - install -m 0644 modem-config-dump.service ${D}${systemd_unitdir}/system/ - - install -d ${D}/usr/bin - install -m 0755 modem-config-dump.py ${D}/usr/bin/modem-config-dump -} - diff --git a/recipes-connectivity/sim-config/files/sim-config.py b/recipes-connectivity/sim-config/files/sim-config.py deleted file mode 100755 index 88de4c6..0000000 --- a/recipes-connectivity/sim-config/files/sim-config.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python3 - -import serial -import os -import time -import configparser -import sys - -CONFIG = '/etc/sim.conf' -SERIAL_DEV = '/dev/ttyACM0' -GPIO_PATH = '/sys/class/gpio/' -GPIO_SIM_SW = '44' -GPIO_SIM_RST = '57' -RST_FILE = '/tmp/modem-reset-required' - -rst = False - -def write_to_file(file, value): - f = open(file, 'w') - f.write(value) - f.close() - -def reset_modem(): - print("modem reset") - write_to_file(GPIO_PATH + 'export', GPIO_SIM_RST) - write_to_file(GPIO_PATH + 'gpio' + GPIO_SIM_RST + '/direction', 'out') - write_to_file(GPIO_PATH + 'gpio' + GPIO_SIM_RST + '/value', '1') - time.sleep(2) - write_to_file(GPIO_PATH + 'gpio' + GPIO_SIM_RST + '/value', '0') - # Wait until modem rebooted - while os.path.exists('/dev/ttyACM0'): - time.sleep(1) - while not os.path.exists('/dev/ttyACM0'): - time.sleep(1) - print("reset done") - -def is_rst_required(): - global rst - if rst: - return True - elif os.path.exists(RST_FILE): - return True - else: - return False - -def switch_sim(): - global rst - 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') - rst = True - -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(): - while not os.path.exists(SERIAL_DEV): - time.sleep(1) - - ser = serial.Serial(SERIAL_DEV, 115200, timeout=0.5) - while True: - try: - ser.read() - break - except Exception: - pass - - if sim_present(ser): - print("sim present") - else: - print("no sim, switching to esim") - switch_sim() - ser.close() - -def read_config(): - config = configparser.ConfigParser() - config.read(CONFIG) - print(config.get('default', 'SIM')) - sim = config.get('default', 'SIM') - if sim == 'auto': - check_sim_presence() - elif sim == 'esim' or sim == 'ui-top': - switch_sim() - # ui-btm and main are default - if is_rst_required(): - reset_modem() - - -read_config(); - - diff --git a/recipes-connectivity/sim-config/files/sim-config.service b/recipes-connectivity/sim-config/files/sim-config.service deleted file mode 100644 index c014032..0000000 --- a/recipes-connectivity/sim-config/files/sim-config.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -After=ublox-config.service - -[Service] -Type=oneshot -ExecStart=/usr/bin/sim-config - -[Install] -WantedBy=ModemManager.service - - diff --git a/recipes-connectivity/sim-config/sim-config.bb b/recipes-connectivity/sim-config/sim-config.bb deleted file mode 100644 index 505c7c8..0000000 --- a/recipes-connectivity/sim-config/sim-config.bb +++ /dev/null @@ -1,43 +0,0 @@ -SUMMARY = "Select the wanted sim card" -DESCRIPTION = "Allows to select which sim card to use from a config file" -AUTHOR = "Alexandre Bard" - -SECTION = "connectivity" -LICENSE = "GPLv2+" -LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" -PR = "r2" - -RDEPENDS_${PN}="python3-pyserial" - -inherit systemd - -SRC_URI = " \ - file://sim-config.service \ - file://sim-config.py \ - file://sim.conf \ - " - -S = "${WORKDIR}" - -INHIBIT_PACKAGE_DEBUG_SPLIT = "1" - -SYSTEMD_SERVICE_${PN} = "sim-config.service" -SYSTEMD_AUTO_ENABLE ?= "enable" - -FILES_${PN}_append = " \ - /lib \ - /usr \ - /etc \ - " - -do_install () { - install -d ${D}${systemd_unitdir}/system/ - install -m 0644 sim-config.service ${D}${systemd_unitdir}/system/ - - install -d ${D}/usr/bin - install -m 0755 sim-config.py ${D}/usr/bin/sim-config - - install -d ${D}/etc - install -m 0644 sim.conf ${D}/etc/ -} - diff --git a/recipes-connectivity/ublox-configuration/files/modem-config-dump.py b/recipes-connectivity/ublox-configuration/files/modem-config-dump.py new file mode 100755 index 0000000..ff4dec2 --- /dev/null +++ b/recipes-connectivity/ublox-configuration/files/modem-config-dump.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 + +import serial +import os +import time +import re + +CONF_PATH = '/run/modem' + + +def usb_profile_parser(output): + x = re.search('UUSBCONF:\s\d,"(.*)",', output) + return x.group(1) + +def mode_parser(output): + x = re.search('UBMCONF:\s(\d)', output) + mode = int(x.group(1)) + if mode == 1: + return "Router" + elif mode == 2: + return "Bridge" + else: + return "unsupported" + +def apn_parser(output): + x = re.search('","(.*)",', output) + return x.group(1) + +def default_parser(output): + x = re.search('(.*)\n.*\nOK',output) + return x.group(1) + +def read_config(ser, config_file, full_config_file, cmd, label='', parser=default_parser): + + while True: + try: + ser.flushInput() + ser.write(cmd) + ser.write(b'\r') + s = ser.read_until(b'OK') + if(len(s.decode('utf-8')) < 4): # Avoid empty response just after reset + continue + break + except Exception as e: + print("Exception : " + str(e)) + time.sleep(1) + continue + + full_conf = label + '\n' + s.decode('utf-8').strip("OK") + conf = (label + ':').ljust(20) + parser(s.decode('utf-8')) + '\n' + + full_config_file.write(full_conf) + config_file.write(conf) + +def dump_modem_config(ser): + os.makedirs(CONF_PATH, exist_ok=True) + full_config_file = open(CONF_PATH + '/modem-at.config', 'w') + config_file = open(CONF_PATH + '/modem.config', 'w') + + read_config(ser, config_file, full_config_file, b'AT+CGMI', 'VendorID') + read_config(ser, config_file, full_config_file, b'AT+CGMM', 'ModelID') + read_config(ser, config_file, full_config_file, b'AT+CGMR', 'Firmware') + + full_config_file.write('-' * 80 + '\n' * 2) + + read_config(ser, config_file, full_config_file, b'AT+UCGDFLT?', 'Default APN', apn_parser) + read_config(ser, config_file, full_config_file, b'AT+UBMCONF?', 'Mode', mode_parser) + read_config(ser, config_file, full_config_file, b'AT+UUSBCONF?', 'USBprofile', usb_profile_parser) \ No newline at end of file diff --git a/recipes-connectivity/sim-config/files/sim.conf b/recipes-connectivity/ublox-configuration/files/sim.conf similarity index 100% rename from recipes-connectivity/sim-config/files/sim.conf rename to recipes-connectivity/ublox-configuration/files/sim.conf diff --git a/recipes-connectivity/ublox-configuration/files/ublox-config.py b/recipes-connectivity/ublox-configuration/files/ublox-config.py index 1c87319..bfdc094 100755 --- a/recipes-connectivity/ublox-configuration/files/ublox-config.py +++ b/recipes-connectivity/ublox-configuration/files/ublox-config.py @@ -4,18 +4,25 @@ import serial import sys import time import os +import configparser +config_dump = __import__("modem-config-dump") -MAX_TRY = 5 -tries = 0 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' -while not os.path.exists(SERIAL_DEV): - time.sleep(1) +def write_to_file(file, value): + f = open(file, 'w') + f.write(value) + f.close() -ser = serial.Serial(SERIAL_DEV, 115200, timeout=0.5) - -def execute_and_check(cmd): - global tries +def execute_and_check(ser, cmd): + tries = 0 + MAX_TRY = 5 ser.flushInput() ser.write(cmd) ser.write(b'\r') @@ -26,25 +33,123 @@ def execute_and_check(cmd): tries += 1 if tries < MAX_TRY: time.sleep(1) - execute_and_check(cmd) + 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') -print("Setting up bridge mode") -execute_and_check(b'AT+UBMCONF=2') +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 -print("Setting up USB mode to ECM") -execute_and_check(b'AT+UUSBCONF=2,"ECM",0') +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 -print("Resetting modem") -# Let the reset be done by sim-config to avoid 2 resets -# ser.write(b'AT+CFUN=16\r') -f = open('/tmp/modem-reset-required', 'w') -f.write('1') -f.close() + config = configparser.ConfigParser() + config.read(APN_CONFIG) -ser.close() + 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() diff --git a/recipes-connectivity/ublox-configuration/files/ublox-config.service b/recipes-connectivity/ublox-configuration/files/ublox-config.service index b103e4d..33d1223 100644 --- a/recipes-connectivity/ublox-configuration/files/ublox-config.service +++ b/recipes-connectivity/ublox-configuration/files/ublox-config.service @@ -1,9 +1,9 @@ [Unit] -Before=sim-config.service +Before=ModemManager.service [Service] Type=oneshot -ExecStart=/bin/bash -c "ifconfig wwan0 && { echo 'already configured'; exit 0; };/usr/bin/ublox-config;" +ExecStart=/usr/bin/ublox-config [Install] WantedBy=ModemManager.service diff --git a/recipes-connectivity/ublox-configuration/ublox-configuration.bb b/recipes-connectivity/ublox-configuration/ublox-configuration.bb index 2b683b8..1c84d97 100644 --- a/recipes-connectivity/ublox-configuration/ublox-configuration.bb +++ b/recipes-connectivity/ublox-configuration/ublox-configuration.bb @@ -9,11 +9,13 @@ PR = "r2" RDEPENDS_${PN}="python3-pyserial" -inherit systemd +inherit systemd python3-dir SRC_URI = " \ file://ublox-config.service \ file://ublox-config.py \ + file://modem-config-dump.py \ + file://sim.conf \ " S = "${WORKDIR}" @@ -34,5 +36,13 @@ do_install () { install -d ${D}/usr/bin install -m 0755 ublox-config.py ${D}/usr/bin/ublox-config + + install -d ${D}${PYTHON_SITEPACKAGES_DIR} + install -m 0755 modem-config-dump.py ${D}${PYTHON_SITEPACKAGES_DIR}/ + + install -d ${D}/etc + install -m 0644 sim.conf ${D}/etc/ + } +