xbee: cellular: add PLSx3 firmware updater recipe and helper script

Add new `glinswup-PLSx3_1.0.5.bb` binary recipe to package the
Cinterion PLSx3 firmware update tool.

Include `pls3_fw_update.sh` helper script to:
- validate input firmware file and modem port
- stop modem-related services before update
- run `glinswup_PLSx3` firmware update
- restore services on exit

https://onedigi.atlassian.net/browse/DEL-9989

Signed-off-by: Francisco Gil <francisco.gilmartinez@digi.com>
This commit is contained in:
Francisco Gil 2026-02-27 12:08:05 +01:00
parent 35dd3ec6c9
commit 3b9a8698a7
2 changed files with 194 additions and 0 deletions

View File

@ -0,0 +1,164 @@
#!/bin/sh
#===============================================================================
#
# Copyright (C) 2026 by Digi International Inc.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as published by
# the Free Software Foundation.
#
#
# Description:
# Update firmware on a Cinterion PLSx3 modem using glinswup_PLSx3.
#
#
# Usage:
# pls3_fw_update.sh -f <firmware.usf> -p <port> [-n] [-v]
#
#===============================================================================
set -eu
UPDATE_BIN="glinswup_PLSx3"
MM_SERVICE_SYSTEMD=${MM_SERVICE_SYSTEMD:-ModemManager}
# On sysvinit-based platforms, NetworkManager respawns ModemManager automatically.
# Therefore we must stop NetworkManager to ensure ModemManager remains stopped
# during the firmware update process.
NM_SERVICE_VINIT=${NM_SERVICE_VINIT:-networkmanager}
FW_FILE=""
PORT=""
VERBOSE=0
RECOVERY=0
exit_error()
{
ERROR_MESSAGE="$1"
ERROR_CODE="${2:-1}"
echo "## ERROR: ${ERROR_MESSAGE}" >&2
exit "${ERROR_CODE}"
}
log_info()
{
echo "## INFO: $*"
}
stop_services()
{
if command -v systemctl >/dev/null 2>&1; then
log_info "Stopping ${MM_SERVICE_SYSTEMD}..."
systemctl stop "${MM_SERVICE_SYSTEMD}" >/dev/null 2>&1 || true
return 0
fi
if [ -x "/etc/init.d/${NM_SERVICE_VINIT}" ]; then
log_info "Stopping ${NM_SERVICE_VINIT}..."
"/etc/init.d/${NM_SERVICE_VINIT}" stop >/dev/null 2>&1 || true
return 0
fi
log_info "No service manager found; skipping stop/start"
return 0
}
start_services()
{
if command -v systemctl >/dev/null 2>&1; then
systemctl start "${MM_SERVICE_SYSTEMD}" >/dev/null 2>&1 || true
return 0
fi
if [ -x "/etc/init.d/${NM_SERVICE_VINIT}" ]; then
"/etc/init.d/${NM_SERVICE_VINIT}" start >/dev/null 2>&1 || true
return 0
fi
return 0
}
usage()
{
cat <<'EOF'
Usage:
pls3_fw_update.sh -f <firmware.usf> -p <port> [-n] [-v]
Options:
-f, --firmware Path to firmware file (.usf)
-p, --port Serial port used by the updater tool (e.g. /dev/ttyACM0)
-n Recovery mode (pass -n to updater)
-v Verbose (pass -v to updater and show output)
Environment:
MM_SERVICE_SYSTEMD=ModemManager
NM_SERVICE_VINIT=networkmanager
EOF
}
parse_args()
{
while [ $# -gt 0 ]; do
case "$1" in
-f|--firmware)
[ $# -ge 2 ] || exit_error "Missing value for $1" 2
FW_FILE="${2:-}"; shift 2;;
-p|--port)
[ $# -ge 2 ] || exit_error "Missing value for $1" 2
PORT="${2:-}"; shift 2;;
-n)
RECOVERY=1; shift;;
-v)
VERBOSE=1; shift;;
-h|--help)
usage; exit 0;;
*)
exit_error "Unknown argument: $1" 2;;
esac
done
}
require_prereqs()
{
[ -n "${FW_FILE}" ] || exit_error "Missing -f/--firmware" 2
[ -n "${PORT}" ] || exit_error "Missing -p/--port" 2
[ -r "${FW_FILE}" ] || exit_error "Firmware file not readable: ${FW_FILE}" 2
command -v "${UPDATE_BIN}" >/dev/null 2>&1 || exit_error "Update tool not found in PATH: ${UPDATE_BIN}" 2
[ -e "${PORT}" ] || exit_error "Port does not exist: ${PORT}" 2
}
run_update()
{
RC=0
VERBOSE_ARG=""
RECOVERY_ARG=""
[ "${VERBOSE}" -eq 1 ] && VERBOSE_ARG="-v"
[ "${RECOVERY}" -eq 1 ] && RECOVERY_ARG="-n"
log_info "Running: ${UPDATE_BIN} -f '${FW_FILE}' -p '${PORT}' -u 1 ${RECOVERY_ARG} ${VERBOSE_ARG}"
if [ "${VERBOSE}" -eq 1 ]; then
"${UPDATE_BIN}" -f "${FW_FILE}" -p "${PORT}" -u 1 ${RECOVERY_ARG} ${VERBOSE_ARG} || RC=$?
else
"${UPDATE_BIN}" -f "${FW_FILE}" -p "${PORT}" -u 1 ${RECOVERY_ARG} >/dev/null 2>&1 || RC=$?
fi
if [ "${RC}" -ne 0 ]; then
exit_error "Firmware update FAILED (exit code: ${RC})" "${RC}"
fi
log_info "Firmware update SUCCESS"
}
parse_args "$@"
require_prereqs
stop_services
# Always try to restore services even if the update fails.
trap 'start_services' EXIT
run_update

View File

@ -0,0 +1,30 @@
# Copyright (C) 2026, Digi International Inc.
SUMMARY = "Cinterion PLSx3 firmware update tool (glinswup) + helper script"
SECTION = "console/tools"
LICENSE = "CLOSED"
PKGNAME = "glinswup_PLSx3"
# ARM tarball
SRC_URI:arm += "${DIGI_PKG_SRC}/${PKGNAME}-${PV}-arm.tar.gz;name=arm"
SRC_URI[arm.md5sum] = "e89f7e3e9cc97f4df51366d4a93e7542"
SRC_URI[arm.sha256sum] = "ca274365c244c3b43ce3e2e3b7b13c70a4104645673c7324a4cbc18132e28a86"
# AARCH64 tarball
SRC_URI:aarch64 += "${DIGI_PKG_SRC}/${PKGNAME}-${PV}-aarch64.tar.gz;name=aarch64"
SRC_URI[aarch64.md5sum] = "4e44cd327ce7fe430e1d60d66ae7528e"
SRC_URI[aarch64.sha256sum] = "3f70500a4c6c280c3c42259fa51abc565fb76c97d4cea64aed36a3539b168c38"
SRC_URI += " file://pls3_fw_update.sh"
S = "${WORKDIR}/${PKGNAME}_${PV}"
do_install:append() {
install -d ${D}${sbindir}
install -m 0755 ${WORKDIR}/pls3_fw_update.sh ${D}${sbindir}/pls3_fw_update.sh
}
inherit bin_package
INSANE_SKIP:${PN} = "already-stripped"