diff options
author | Alex Elder <elder@linaro.org> | 2022-06-30 17:39:08 -0500 |
---|---|---|
committer | Alex Elder <elder@linaro.org> | 2022-06-30 17:42:48 -0500 |
commit | 8dce05b263a8f016afe85789cb277aed5d4126af (patch) | |
tree | 6bcf3a717a679089772401200bd1466017111d47 |
Initial commit
Add a script that performs all the QMI work that "ipa-test" does,
but use "qmicli" for all QMI commands. This assumes the modem NV
data has already been configured for loopback operation.
The "loopback_config" script initializes the modem link, then does a
ping request to demonstrate the link works. It then tears down the
data connection.
Note that this works only once... I'm going to split up the script
a bit so that it separates enabling the loopback link and disabling
it. It *should* be possible to stop and re-start a call, but so far
I haven't figured out how.
Signed-off-by: Alex Elder <elder@linaro.org>
-rwxr-xr-x | loopback_config | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/loopback_config b/loopback_config new file mode 100755 index 0000000..eebae6d --- /dev/null +++ b/loopback_config @@ -0,0 +1,285 @@ +#!/bin/bash + +# Set up temp files +cleanup() { + rm -f "${ERR}" + rm -f "${OUT}" +} + +trap cleanup EXIT + +OUT="$(mktemp /tmp/out.XXXXXX)" || exit 1 +ERR="$(mktemp /tmp/err.XXXXXX)" || exit 1 + +# Define modem information + +APN="fast.t-mobile.com" # T-Mobile +# APN="h2g2" # Google Fi +# APN="vzwinternet" # Verizon +# APN="pwg" # US Mobile +# APN="phone" # AT&T +# APN="Boost_Mobile" # Boost Mobile + +DEVICE="qrtr://0" + +EP_TYPE="embedded" +IFACE_NUMBER="1" + +MAP_MUX_ID="1" + +##### Functions to gather IPA hardware information + +# Record AP<-modem RX and AP->modem TX endpoint IDs +get_ipa_endpoints() { + [ $# -eq 1 ] || exit 1 + local ipa_dir="$1" + local endpoint_dir="${ipa_dir}/endpoint_id" + local modem_rx_file="${endpoint_dir}/modem_rx" + local modem_tx_file="${endpoint_dir}/modem_tx" + + [ -d "${endpoint_dir}" ] || exit 1 + [ -f "${modem_rx_file}" ] || exit 1 + [ -f "${modem_tx_file}" ] || exit 1 + + AP_MODEM_RX_ENDPOINT=$(cat "${modem_rx_file}") + AP_MODEM_TX_ENDPOINT=$(cat "${modem_tx_file}") + + echo Using AP_MODEM_RX_ENDPOINT = "${AP_MODEM_RX_ENDPOINT}" >&2 + echo Using AP_MODEM_TX_ENDPOINT = "${AP_MODEM_TX_ENDPOINT}" >&2 +} + +# sysfs shows "MAPv5"; qmicli wants "qmapv5" +translate_offload() { + [ $# -eq 1 ] || exit 1 + local file="$1" + + [ -f "${file}" ] || exit 1 + + echo q$(cat "${file}" | tr '[:upper:]' '[:lower:]') +} + +get_ipa_features() { + [ $# -eq 1 ] || exit 1 + local ipa_dir="$1" + local feature_dir="${ipa_dir}/feature" + + [ -d "${feature_dir}" ] || exit 1 + + RX_OFFLOAD=$(translate_offload "${feature_dir}/rx_offload") + TX_OFFLOAD=$(translate_offload "${feature_dir}/tx_offload") + + echo Using RX_OFFLOAD = "${RX_OFFLOAD}" >&2 + echo Using TX_OFFLOAD = "${TX_OFFLOAD}" >&2 +} + +# Gather IPA information +get_ipa_info() { + local ipa_dir="$(echo /sys/devices/platform/soc@0/*.ipa)" + + [ -d "${ipa_dir}" ] || exit 1 + + get_ipa_endpoints "${ipa_dir}" + get_ipa_features "${ipa_dir}" +} + +# Grab a value reported in qmicli output +get_value() { + [ $# -eq 1 ] || exit 1 + local key="$1" + + eval echo $(grep "${key}:" "${OUT}" | awk '{print $NF}') +} + +###### Client ID functions + +# Usage: CID=$(create_cid SERVICE) +# where SERVICE is dpm, wda, or wds +# XXX For some reason, wds returns 2; others return 1 +create_cid() { + [ $# -eq 1 ] || exit 1 + local service="$1" + + qmicli --device "${DEVICE}" --device-open-proxy \ + --client-no-release-cid \ + --${service}-noop > "${OUT}" 2> "${ERR}" + + # Return (echo) the CID created (found in the output file) + get_value CID +} + +# Usage: destroy_cid SERVICE CID +# where SERVICE is dpm, wda, or wds; and CID is its previously created CID +destroy_cid() { + [ $# -eq 2 ] || exit 1 + local service="$1" + local cid="$2" + + qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid="${cid}" \ + --${service}-noop > "${OUT}" 2> "${ERR}" +} + +# ============== Start + +get_ipa_info + +# -------- DPM -------- + +# Create a persistent CID to use for DPM service +DPM_CLIENT_CID=$(create_cid dpm) + +# Open the interface port, and associate the IPA endpoints + +ARGS="hw-data-ep-type=${EP_TYPE}" +ARGS="${ARGS},hw-data-ep-iface-number=${IFACE_NUMBER}" +ARGS="${ARGS},hw-data-rx-id=${AP_MODEM_TX_ENDPOINT}" +ARGS="${ARGS},hw-data-tx-id=${AP_MODEM_RX_ENDPOINT}" + +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${DPM_CLIENT_CID} --client-no-release-cid \ + --dpm-open-port="${ARGS}" > "${OUT}" 2> "${ERR}" + +# -------- WDA -------- + +# Create a persistent CID to use for WDA service +WDA_CLIENT_CID=$(create_cid wda) + +# Set the data format for embedded interface 1 + +ARGS="ep-type=${EP_TYPE}" +ARGS="${ARGS},ep-iface-number=${IFACE_NUMBER}" +ARGS="${ARGS},link-layer-protocol=raw-ip" +ARGS="${ARGS},ul-protocol=${TX_OFFLOAD}" +ARGS="${ARGS},dl-protocol=${RX_OFFLOAD}" +ARGS="${ARGS},dl-datagram-max-size=1504" +ARGS="${ARGS},dl-max-datagrams=1" + +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${WDA_CLIENT_CID} --client-no-release-cid \ + --wda-set-data-format="${ARGS}" > "${OUT}" 2> "${ERR}" + +# -------- WDS -------- + +# Create a persistent CID to use for WDS service +WDS_CLIENT_CID=$(create_cid wds) + +# Bind to the MUX ID on the embedded interface + +ARGS="ep-type=${EP_TYPE}" +ARGS="${ARGS},ep-iface-number=${IFACE_NUMBER}" +ARGS="${ARGS},mux-id=${MAP_MUX_ID}" + +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${WDS_CLIENT_CID} --client-no-release-cid \ + --wds-bind-mux-data-port="${ARGS}" > "${OUT}" 2> "${ERR}" + +# Now start the interface + +ARGS="ip-type=4" +ARGS="${ARGS},apn=${APN}" + +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${WDS_CLIENT_CID} --client-no-release-cid \ + --wds-start-network="${ARGS}" > "${OUT}" 2> "${ERR}" +PACKET_DATA_HANDLE=$(get_value 'Packet data handle') + +echo Using PACKET_DATA_HANDLE = "${PACKET_DATA_HANDLE}" >&2 + +# Find out the IP settings that should be used +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${WDS_CLIENT_CID} --client-no-release-cid \ + --wds-get-current-settings > "${OUT}" 2> "${ERR}" +IPV4_ADDRESS=$(get_value 'IPv4 address') +IPV4_SUBNET=$(get_value 'IPv4 subnet mask') +IPV4_GATEWAY=$(get_value 'IPv4 gateway address') + +echo Using IPV4_ADDRESS = "${IPV4_ADDRESS}" >&2 +echo Using IPV4_SUBNET = "${IPV4_SUBNET}" >&2 +echo Using IPV4_GATEWAY = "${IPV4_GATEWAY}" >&2 + +# -------- IP -------- + +# For some reason, rmnet_data0 has already been created +# ip link add link rmnet_ipa0 name rmnet_data0 type rmnet mux_id "${MAP_MUX_ID}" + +# Assign rmnet_data0 its IPA address and netmask +ip addr add ${IPV4_ADDRESS}/${IPV4_SUBNET} dev rmnet_data0 + +# Link rmnet_ipa0 is already up +# ip link set rmnet_ipa0 up + +# Bring up rmnet_data0 +ip link set rmnet_data0 up + +######### That should be it + +echo ============= rmnet_data0 IP "${IPV4_ADDRESS}" +sleep 2 + +# NET=${IPV4_ADDRESS%.*} +# NODE=${IPV4_ADDRESS##*.} + +ping -c 3 -I rmnet_data0 "${IPV4_GATEWAY}" + +sleep 2 +echo ============= Now reversing setup + +# ============== Undo + +# -------- IP -------- + +# Bring down rmnet_data0 +ip link set rmnet_data0 down + +# Leave rmnet_ipa0 up +# ip link set rmnet_ipa0 down + +# Delete the IP address we assigned to rmnet_data0 +ip addr del ${IPV4_ADDRESS}/${IPV4_SUBNET} dev rmnet_data0 + +# Don't destroy link rmnet_data0, because we didn't create it +# ip link delete rmnet_data0 type rmnet mux_id "${MAP_MUX_ID}" + +# -------- WDS -------- + +unset IPV4_GATEWAY +unset IPV4_SUBNET +unset IPV4_ADDRESS + +# Stop the interface + +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${WDS_CLIENT_CID} --client-no-release-cid \ + --wds-stop-network="${PACKET_DATA_HANDLE}" > "${OUT}" 2> "${ERR}" + +unset PACKET_DATA_HANDLE + +# Un-bind the MUX ID on the embedded interface by binding it to MUX ID 0 + +ARGS="ep-type=${EP_TYPE}" +ARGS="${ARGS},ep-iface-number=${IFACE_NUMBER}" +ARGS="${ARGS},mux-id=0" + +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${WDS_CLIENT_CID} --client-no-release-cid \ + --wds-bind-mux-data-port="${ARGS}" > "${OUT}" 2> "${ERR}" + +destroy_cid wds "${WDS_CLIENT_CID}" + +# -------- WDA -------- + +# No need to un-set the data format for embedded interface 1? + +destroy_cid wda "${WDA_CLIENT_CID}" + +unset WDA_CLIENT_CID + +# -------- DPM -------- + +qmicli --device "${DEVICE}" --device-open-proxy \ + --client-cid=${DPM_CLIENT_CID} --client-no-release-cid \ + --dpm-close-port > "${OUT}" 2> "${ERR}" + +destroy_cid dpm "${DPM_CLIENT_CID}" + +unset DPM_CLIENT_CID |