blob: faf07fcaafbc61819fe935083864a4f4d2649e3c [file] [log] [blame]
#!/bin/bash -e
# Copyright 2022 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
VERSION="MODEM-TIME-SAMPLES-RESET-GENERIC_V1.0.5"
readonly PROG="$(basename "$0")"
readonly PID="$$"
echo $PID
readonly LOG_TAG='modem-time-samples'
readonly LOCK_FILE=/run/lock/modem-time-samples.lock
readonly RESULT_FILE=/tmp/modem-time-samples.log
# Starting from Coral Proto2, EN_PP3300_DX_LTE is controlled via this GPIO
EN_GPIO=311
readonly EN_GPIO_ON=1
readonly EN_GPIO_OFF=0
chromeos_cfg_file="/etc/lsb-release"
readonly WWAN_IF='wwan0'
readonly DELAY_AFTER_POWER_OFF_SECONDS=5
readonly TIMEOUT_SECONDS=60
# Adjust these parameters accordingly
MODEM_USB_VID_PID='2CB7:0007'
readonly APN='internet'
readonly DEFAULT_NUM_ITERATIONS=1
readonly COLOR_HIGHLIGHT='\033[1;32m'
readonly COLOR_RESET='\033[0m'
log_info() {
logger -t "${LOG_TAG}" --id="$$" -p info "$*"
echo " INFO: $*" > /dev/stderr
}
log_warning() {
logger -t "${LOG_TAG}" --id="$$" -p warn "$*"
echo "WARNING: $*" > /dev/stderr
}
log_error() {
logger -t "${LOG_TAG}" --id="$$" -p err "$*"
echo " ERROR: $*" > /dev/stderr
}
die() {
log_error "$@"
exit 1
}
get_timestamp() {
date '+%s.%N'
}
set_en_gpio() {
local customer=""
if [ ! -f "$chromeos_cfg_file" ]; then
echo "$modemfwd_cfg_file is not exist"
customer="other"
else
board_line=`cat /etc/lsb-release | grep CHROMEOS_RELEASE_BUILDER_PATH`
echo "$board_line" > board_newline
customer=$(cut -d = -f 2 board_newline|cut -d - -f 1)
rm -rf board_newline
fi
echo "$customer"
if [ "$customer" == "nautilus" ];then
echo "it's samsung platform, use EN_GPIO=432"
EN_GPIO=432
elif [ "$customer" == "coral" ];then
echo "it's acer platform, use EN_GPIO=395"
EN_GPIO=395
elif [ "$customer" == "quanta" ];then
echo "it's quanta platform, use EN_GPIO=395"
EN_GPIO=395
elif [ "$customer" == "sarien" ];then
echo "it's dell platform, use EN_GPIO=311"
EN_GPIO=311
elif [ "$customer" == "drallion" ];then
echo "it's drallion platform, use EN_GPIO=466"
EN_GPIO=466
elif [ "$customer" == "hatch" ];then
echo "it's hatch platform, use EN_GPIO=218"
EN_GPIO=218
elif [ "$customer" == "dedede" ];then
echo "it's dedede platform, use EN_GPIO=349"
EN_GPIO=349
elif [ "$customer" == "zork" ];then
echo "it's zork platform, use EN_GPIO=345"
EN_GPIO=345
elif [ "$customer" == "brya" ];then
echo "it's brya platform, use EN_GPIO=488"
EN_GPIO=488
elif [ "$customer" == "octopus" ];then
echo "it's octopus platform, use EN_GPIO=337"
# EN_GPIO=393
# set_modem_power "${EN_GPIO_ON}"
# EN_GPIO=499
# set_modem_power "${EN_GPIO_ON}"
EN_GPIO=337
else
echo "$customer customer not support"
# customer="other"
usage
exit 0
fi
}
last_timestamp="$(get_timestamp)"
last_modemstate=""
test_step=1
test_result="\033[1;5;31m [TEST RESULT]\033[0m\n"
print_elapsed_time() {
local description="$1"
local current_modem_state="$2"
local current_state_time="$3"
local current_timestamp="${current_state_time:-$(get_timestamp)}"
if [ -z "${current_modem_state}" ]; then
local elapsed_time=`echo "$current_timestamp - $last_timestamp"|bc`
rt=$(printf "${COLOR_HIGHLIGHT}"'%-30s ===> %30.30s (s): %0.3f\n'"${COLOR_RESET}" "${test_step}.${last_modemstate}" "${description}" "${elapsed_time}")
printf "${rt}"
test_result+=${rt}
((test_step++))
fi
last_timestamp="${current_state_time:-$current_timestamp}"
last_modemstate="${description:-$current_modem_state}"
}
is_service_running() {
local service="$1"
status "${service}" | grep -q 'running'
}
restart_service() {
local service="$1"
shift
if is_service_running "${service}"; then
stop "${service}"
fi
start "${service}" "$@"
}
set_modem_power() {
local new_value="$1"
local gpio_node=/sys/class/gpio/gpio"${EN_GPIO}"
if [ ! -e "${gpio_node}" ]; then
echo "${EN_GPIO}" > /sys/class/gpio/export
[ -e "${gpio_node}" ] || die "Failed to export GPIO ${EN_GPIO}"
fi
local value_file="${gpio_node}"/value
local old_value="$(cat "${value_file}")"
if [ "${old_value}" != "${new_value}" ]; then
echo 'out' > "${gpio_node}"/direction
echo "${new_value}" > "${value_file}"
fi
old_value="$(cat "${value_file}")"
[ "${old_value}" = "${new_value}" ] || die "Failed to update GPIO ${EN_GPIO}"
}
wait_for_modem_usb_device() {
local start_time="$(get_timestamp)"
local elapsed_time=0
while [ `echo "${elapsed_time} < ${TIMEOUT_SECONDS}"|bc` ]; do
if lsusb -d "${MODEM_USB_VID_PID}" >/dev/null; then
return 0
fi
sleep .1
elapsed_time=`echo "$(get_timestamp) - $start_time"|bc`
done
return 1
}
wait_for_modem_object() {
local start_time="$(get_timestamp)"
local elapsed_time=0
while [ `echo "${elapsed_time} < ${TIMEOUT_SECONDS}"|bc` ]; do
local modem_object="$(mmcli -L | grep "ModemManager1")"
if [ -n "${modem_object}" ]; then
return 0
fi
sleep .1
elapsed_time=`echo "$(get_timestamp) - $start_time"|bc`
done
return 1
}
get_modem_object() {
mmcli -L | sed -nE "s|.*/org/freedesktop/ModemManager1/Modem/([0-9]+).*|\1|p"
}
filter_log() {
local pid="$1"
sed -n ':skip {n; /modem-time-samples\['"${pid}"'\]/!b skip}; :start {n; /\(ModemManager\[\|modem-time-samples\[\|kernel\)/p; b start}'
}
get_modem_usb_device() {
if lsusb -d "2CB7:0007" >/dev/null; then
MODEM_USB_VID_PID='2CB7:0007'
elif lsusb -d "2CB7:01a0" >/dev/null; then
MODEM_USB_VID_PID='2CB7:01a0'
else
echo "can't find any modem"
fi
}
setup() {
get_modem_usb_device
log_info 'Power off modem'
set_modem_power "${EN_GPIO_OFF}"
sleep "${DELAY_AFTER_POWER_OFF_SECONDS}"
# log_info 'Restart shill with the WWAN interface ignored'
log_info 'Stop Shill'
stop shill
# restart_service shill DENYLISTED_DEVICES="${WWAN_IF}"
log_info 'Restart ModemManager with log level set to debug'
restart_service modemmanager MM_LOGLEVEL=DEBUG
}
wait_for_3gpp_update() {
while true;do
local modem_id=$(mmcli -L | grep -oE '/org/freedesktop/ModemManager1/Modem/[0-9]+')
echo "modem is $modem_id"
read_3gpp_operator=$(mmcli -m "$modem_id" | sed -n '/operator\ id/p')
read_3gpp_packet=$(mmcli -m "$modem_id" | sed -n '/packet\ service\ state/p')
echo "3gpp operator id is ${read_3gpp_operator}"
echo "3gpp packet service state is ${read_3gpp_packet}"
if [ -n "${read_3gpp_operator}" ] || [ -n "${read_3gpp_packet}" ];then
break;
fi
sleep .1
done
}
wait_for_modem_state() {
local modemstate=$1
while true;do
local modem_id=$(mmcli -L | grep -oE '/org/freedesktop/ModemManager1/Modem/[0-9]+')
echo "modem is $modem_id"
read_connect_state=$(mmcli -m "$modem_id" | grep 'state:' | grep -v 'power')
echo "modem state is ${read_connect_state}"
if [[ "${read_connect_state}" =~ "${modemstate}" ]];then
break;
fi
sleep .1
done
}
run_iteration() {
local iteration="$1"
log_info "[Iteration ${iteration}] Power on modem"
set_modem_power "${EN_GPIO_ON}"
last_timestamp="$(get_timestamp)"
last_modemstate="OFF"
log_info "[Iteration ${iteration}] Wait for modem USB device to appear"
wait_for_modem_usb_device || die 'Modem USB device not found'
print_elapsed_time 'Modem USB enumeration'
log_info "[Iteration ${iteration}] Wait for modem object to initialize"
wait_for_modem_object || die 'Modem object not found'
print_elapsed_time '' 'Modem disabled #1'
local modem_object="$(get_modem_object)"
[ -n "${modem_object}" ] || die 'Modem not found'
log_info "[Iteration ${iteration}] Enable modem"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" -e
print_elapsed_time 'Modem enabled #1'
wait_for_modem_state "registered"
#print_elapsed_time 'Modem registered #1'
log_info "[Iteration ${iteration}] Connect modem to network"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" "--simple-connect=apn=${APN}"
#print_elapsed_time 'Modem connected #1'
#log_info "[Iteration ${iteration}] Disconnect modem to network"
#mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" "--simple-disconnect=apn=${APN}"
#wait_for_modem_state "registered"
#print_elapsed_time 'Modem registered #1'
log_info "[Iteration ${iteration}] Disable modem"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" -d
#print_elapsed_time 'Modem disabled #1'
log_info "[Iteration ${iteration}] Set low power state"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" --set-power-state-low
#print_elapsed_time '' 'Modem suspend #1'
log_info "[Iteration ${iteration}] Set normal power state"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" --set-power-state-on
#print_elapsed_time 'Modem RF enable'
log_info "[Iteration ${iteration}] Enable modem"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" -e
#print_elapsed_time 'Modem enable #2'
wait_for_modem_state "registered"
wait_for_3gpp_update
log_info "[Iteration ${iteration}] Connect modem to network"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" "--simple-connect=apn=${APN}"
#print_elapsed_time '' 'Modem connected #2'
log_info "[Iteration ${iteration}] Disable modem"
mmcli --timeout="${TIMEOUT_SECONDS}" -m "${modem_object}" -d
#print_elapsed_time 'Modem disabled #2'
log_info "[Iteration ${iteration}] Power off modem"
set_modem_power "${EN_GPIO_OFF}"
sleep "${DELAY_AFTER_POWER_OFF_SECONDS}"
}
collect_result() {
cat /var/log/messages /var/log/net.log | sort | uniq | filter_log "${PID}" > "${RESULT_FILE}"
}
show_last_result() {
cat /var/log/messages /var/log/net.log | sort | uniq | filter_log '.*'
}
cleanup() {
log_info 'Power off modem'
set_modem_power "${EN_GPIO_ON}"
log_info 'Restart shill with default settings'
restart_service shill
log_info 'Restart ModemManager with default settings'
restart_service modemmanager
}
analysis_modem_state_from_log() {
echo "net.log analysising"
local modem_enabled=''
local modem_registered=''
local modem_connected_1st=''
local modem_disabling=''
local modem_3gpp_unknown=''
local modem_disabled=''
local modem_low_power=''
local modem_connected_2nd=''
if [ -f ${RESULT_FILE} ]; then
while read line; do
if [ -z "${modem_enabled}" ]; then
if [[ "${line}" =~ "state changed (enabling -> enabled)" ]]; then
modem_enabled=`date -d "${line%% *}" +%s.%6N`
#echo ${modem_enabled}
echo ${line}
print_elapsed_time '' 'Modem enabled' "${modem_enabled}"
continue
fi
fi
if [ -z "${modem_registered}" ]; then
if [[ "${line}" =~ "state changed (enabled -> registered)" ]]; then
modem_registered=`date -d "${line%% *}" +%s.%6N`
#echo ${modem_registered}
echo ${line}
print_elapsed_time 'Modem registered' '' "${modem_registered}"
continue
fi
fi
if [ -z "${modem_connected_1st}" ]; then
if [[ "${line}" =~ "state changed (connecting -> connected)" ]]; then
modem_connected_1st=`date -d "${line%% *}" +%s.%6N`
#echo $modem_connected_1st
echo ${line}
print_elapsed_time 'Modem connected' '' "${modem_connected_1st}"
continue
fi
fi
if [ -z "${modem_disabling}" ]; then
if [[ "${line}" =~ "state changed (connected -> disabling)" ]]; then
modem_disabling=`date -d "${line%% *}" +%s.%6N`
#echo $modem_disabling
echo ${line}
print_elapsed_time '' 'Modem connected' "${modem_disabling}"
continue
fi
fi
if [ -z "${modem_3gpp_unknown}" ]; then
if [[ "${line}" =~ "state changed (home -> unknown)" ]]; then
modem_3gpp_unknown=`date -d "${line%% *}" +%s.%6N`
#echo $modem_3gpp_unknown
echo ${line}
print_elapsed_time 'Modem registered' '' "${modem_3gpp_unknown}"
continue
fi
fi
if [ -z "${modem_disabled}" ]; then
if [[ "${line}" =~ "state changed (disabling -> disabled)" ]]; then
modem_disabled=`date -d "${line%% *}" +%s.%6N`
#echo $modem_disabled
echo ${line}
print_elapsed_time 'Modem disabled' '' "${modem_disabled}"
continue
fi
fi
if [ -z "${modem_low_power}" ]; then
if [[ "${line}" =~ "low-power" ]] || [[ "${line}" =~ "power state updated: low" ]]; then
modem_low_power=`date -d "${line%% *}" +%s.%6N`
#echo $modem_low_power
echo ${line}
print_elapsed_time '' 'Modem suspend' "${modem_low_power}"
continue
fi
fi
if [ -z "${modem_connected_2nd}" ]; then
if [[ "${line}" =~ "state changed (connecting -> connected)" ]]; then
modem_connected_2nd=`date -d "${line%% *}" +%s.%6N`
#echo $modem_connected_2nd
echo ${line}
print_elapsed_time 'Modem connected' '' "${modem_connected_2nd}"
break
fi
fi
done < ${RESULT_FILE}
fi
}
print_result() {
echo -e "${test_result}"
}
usage() {
cat <<EOT
Usage: ${PROG} [options]
Options:
-l show last result and exit
-n number of iterations
-h help
EOT
}
main() {
echo -e "########## $VERSION ###########"
local show_last_result=0
local show_help=0
local num_iterations="${DEFAULT_NUM_ITERATIONS}"
local opt
while getopts 'hln:' opt; do
case "${opt}" in
h)
show_help=1
;;
l)
show_last_result=1
;;
n)
num_iterations="${OPTARG}"
[[ "${num_iterations}" =~ ^[0-9]+$ ]] || die "Invalid argument: ${OPTARG}"
;;
*)
die "Unknown option: ${opt}"
;;
esac
done
if [ ${show_help} -eq 1 ]; then
usage
exit 0
fi
if [ ${show_last_result} -eq 1 ]; then
show_last_result
exit 0
fi
set_en_gpio
setup
local iteration
for iteration in $(seq 1 "${num_iterations}"); do
run_iteration "${iteration}"
done
collect_result
cleanup
analysis_modem_state_from_log
print_result
}
main "$@"