summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Elder <elder@linaro.org>2022-06-30 17:39:08 -0500
committerAlex Elder <elder@linaro.org>2022-06-30 17:42:48 -0500
commit8dce05b263a8f016afe85789cb277aed5d4126af (patch)
tree6bcf3a717a679089772401200bd1466017111d47
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-xloopback_config285
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