Zxdl | Script
Network operators utilize ZXDL scripts to automate repetitive and time-consuming tasks across ZTE access networks.
4.1 Bulk ONT Provisioning (FTTH Deployments) The most common use case. Instead of manually clicking through a GUI to provision hundreds of homes, an operator writes a ZXDL script containing a list of Serial Numbers (SNs) and corresponding VLAN/Service profiles.
4.2 Service Port and VLAN Management Creating or modifying traffic pipes. zxdl script
4.3 Diagnostic and Alarm Extraction Generating formatted text outputs of network health.
4.4 Bulk Firmware Upgrades (ONTs) Automating the process of pushing new firmware to customer premises equipment (CPE). setting up PPPoE
#!/usr/bin/env bash
set -euo pipefail
# Defaults
CONCURRENCY=4
CHUNK_SIZE=$((8*1024*1024)) # 8MB
OUTFILE=""
RETRIES=5
BACKOFF_BASE=1
usage() cat <<USAGE
Usage: $0 <file-id-or-url> [--concurrency N] [--chunk-size SIZE] [--out FILE]
USAGE
exit 2
# parse args (simple)
if [ $# -lt 1 ]; then usage; fi
TARGET="$1"; shift || true
while [ $# -gt 0 ]; do
case "$1" in
--concurrency) CONCURRENCY="$2"; shift 2;;
--chunk-size) CHUNK_SIZE_STR="$2"; shift 2;;
--out) OUTFILE="$2"; shift 2;;
*) echo "Unknown: $1"; usage;;
esac
done
# parse human-readable chunk size (e.g., 8M, 1G)
parse_size()
local s="$1"
if [[ -z "$s" ]]; then echo "$CHUNK_SIZE"; return; fi
if [[ "$s" =~ ^([0-9]+)([KkMmGg])?$ ]]; then
local num=$BASH_REMATCH[1]
local unit=$BASH_REMATCH[2]
case "$unit:-B" in
K
if [ -n "$CHUNK_SIZE_STR-" ]; then
CHUNK_SIZE=$(parse_size "$CHUNK_SIZE_STR")
fi
# Resolve API URL and metadata
# Accept either full URL or file-id; adapt to ZX API pattern
if [[ "$TARGET" =~ ^https?:// ]]; then
API_URL="$TARGET"
else
API_URL="https://zx.example/api/files/$TARGET"
fi
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
meta_json="$tmpdir/meta.json"
curl -sSf "$API_URL" -o "$meta_json"
# Expect JSON with: filename, size, sha256, chunk_count (optional)
FILENAME=$(jq -r '.filename // empty' "$meta_json")
FILESIZE=$(jq -r '.size // empty' "$meta_json")
SHA256=$(jq -r '.sha256 // empty' "$meta_json")
if [ -z "$FILENAME" ] || [ -z "$FILESIZE" ]; then
echo "API response missing filename or size" >&2; exit 1
fi
OUTFILE=$OUTFILE:-$FILENAME
# Compute chunk ranges
num_chunks=$(( (FILESIZE + CHUNK_SIZE - 1) / CHUNK_SIZE ))
echo "Downloading $OUTFILE ($FILESIZE bytes) in $num_chunks chunks..."
chunk_url_base=$(jq -r '.chunk_url_template // empty' "$meta_json")
# if API gives template like: https://.../files/id/chunks/n
if [ -z "$chunk_url_base" ]; then
# default: API_URL/chunks/<index>
chunk_url_base="$API_URL%//chunks"
fi
# worker function
download_chunk()
local idx=$1
local start=$(( idx * CHUNK_SIZE ))
local end=$(( start + CHUNK_SIZE - 1 ))
if [ $end -gt $((FILESIZE - 1)) ]; then end=$((FILESIZE - 1)); fi
local out="$tmpdir/chunk.$idx"
local url="$chunk_url_base/\n\/$idx"
for attempt in $(seq 1 $RETRIES); do
if curl -sSf -H "Range: bytes=$start-$end" "$url" -o "$out.part"; then
mv "$out.part" "$out"
return 0
fi
sleep $(( BACKOFF_BASE * attempt ))
done
return 1
export -f download_chunk
export CHUNK_SIZE FILESIZE RETRIES BACKOFF_BASE tmpdir chunk_url_base
# Parallel download loop
seq 0 $((num_chunks - 1)) | xargs -n1 -P "$CONCURRENCY" -I{} bash -c 'download_chunk "$@"' _ {}
# Verify all chunks present
for i in $(seq 0 $((num_chunks - 1))); do
[ -f "$tmpdir/chunk.$i" ] || echo "Missing chunk $i"; exit 1;
done
# Assemble
cat $(for i in $(seq 0 $((num_chunks - 1))); do printf "%s/chunk.%d " "$tmpdir" "$i"; done) > "$tmpdir/assembled"
# Optional integrity check
if [ -n "$SHA256" ] && command -v sha256sum >/dev/null 2>&1; then
got=$(sha256sum "$tmpdir/assembled" | awk 'print $1')
if [ "$got" != "$SHA256" ]; then
echo "SHA256 mismatch: expected $SHA256 got $got" >&2; exit 1
fi
fi
# Move atomically
mv "$tmpdir/assembled" "$OUTFILE"
echo "Saved to $OUTFILE"
Let’s build a functional ZXDL script from scratch. For demonstration, we will assume a syntax similar to a hybrid of INI and bash.
If you are looking for a script to automate the configuration of a ZTE ZXDSL modem (e.g., setting up PPPoE, changing WiFi settings, or rebooting), Python with the telnetlib library is the standard method. These modems often use Telnet for backend management. changing WiFi settings
Here is a full script example to log in and execute commands:
import telnetlib
import time
def configure_zxdsl_modem(host, username, password, commands):
"""
Connects to a ZXDSL modem via Telnet and executes a list of commands.
"""
try:
# Connect to the modem
print(f"Connecting to host...")
tn = telnetlib.Telnet(host, timeout=10)
# Login sequence
tn.read_until(b"Login: ", timeout=5)
tn.write(username.encode('ascii') + b"\n")
tn.read_until(b"Password: ", timeout=5)
tn.write(password.encode('ascii') + b"\n")
# Wait for the prompt (common ZTE prompts are # or >)
time.sleep(2)
print("Logged in successfully. Executing commands...")
# Execute commands
for cmd in commands:
print(f"Executing: cmd")
tn.write(cmd.encode('ascii') + b"\n")
time.sleep(1) # Wait for command to process
# Exit session
tn.write(b"exit\n")
output = tn.read_all().decode('ascii')
print("Configuration complete.")
print("--- Output ---")
print(output)
except Exception as e:
print(f"Error: e")
# --- USAGE ---
# Default ZXDSL credentials are often admin/admin or admin/1234
modem_ip = "192.168.1.1" # Default gateway
user = "admin"
pwd = "admin"
# List of CLI commands to run (varies by firmware version)
# Examples for ZXDSL 831II:
command_list = [
"wan show", # Show WAN status
"lan show", # Show LAN status
"reboot", # Reboot the device (use with caution)
# "save" # Save configuration (if required by model)
]
if __name__ == "__main__":
configure_zxdsl_modem(modem_ip, user, pwd, command_list)