#!/bin/sh # Copyright (C) 2019 iopsys Software Solutions AB # Author: IMEN Bhiri # Author: AMIN Ben Ramdhane UCI_CONFIG_DIR="/etc/config/" UCI_GET_VARSTATE="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state get" UCI_SET_VARSTATE="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state set" UCI_ADD_VARSTATE="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state add" UCI_DELETE_VARSTATE="/sbin/uci -q ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state delete" CAPTURE_FILE="/tmp/download_dump" DOWNLOAD_DIAGNOSTIC_FILE="/tmp/bbfdm_download_diagnostic" DOWNLOAD_DIAGNOSTIC_LOG_FILE="/tmp/bbfdm_download_diagnostic_log" CONNECTION_TIMEOUT=10 download_get() { local val=`$UCI_GET_VARSTATE $1` echo ${val:-$2} } download_launch() { local tx_bytes_before rx_bytes_before time1 tx_bytes_after rx_bytes_after time2 res rh ba stc periodtime local url=$2 local interface=$3 [ "$1" == "cwmp" ] && [ "`$UCI_GET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState`" != "Requested" ] && return [ "$url" = "" ] && { $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=Error_InitConnectionFailed; return; } local proto=`download_get cwmp.@downloaddiagnostic[0].ProtocolVersion Any` # Disable acceleration on Broadcom devices to capture all packets with tcpdump [ -e /usr/sbin/fcctl ] && { fcctl disable >/dev/null 2>&1; fcctl flush >/dev/null 2>&1; } tcpdump -i $interface tcp -w ${CAPTURE_FILE} > /dev/null 2>&1 & PID=$! sleep 1 if [ ${url:0:7} = http:// -o ${url:0:6} = ftp:// ]; then tx_bytes_before=`ubus call network.device status "{'name':'$interface'}" | jsonfilter -e @.statistics.tx_bytes` rx_bytes_before=`ubus call network.device status "{'name':'$interface'}" | jsonfilter -e @.statistics.rx_bytes` time1=`date +%s` [ "$proto" = "Any" ] && res=$(wget -t 1 --timeout=${CONNECTION_TIMEOUT} -O ${DOWNLOAD_DIAGNOSTIC_FILE} -o ${DOWNLOAD_DIAGNOSTIC_LOG_FILE} $url 2>&1) [ "$proto" = "IPv4" ] && res=$(wget -4 -t 1 --timeout=${CONNECTION_TIMEOUT} -O ${DOWNLOAD_DIAGNOSTIC_FILE} -o ${DOWNLOAD_DIAGNOSTIC_LOG_FILE} $url 2>&1) [ "$proto" = "IPv6" ] && res=$(wget -6 -t 1 --timeout=${CONNECTION_TIMEOUT} -O ${DOWNLOAD_DIAGNOSTIC_FILE} -o ${DOWNLOAD_DIAGNOSTIC_LOG_FILE} $url 2>&1) time2=`date +%s` tx_bytes_after=`ubus call network.device status "{'name':'$interface'}" | jsonfilter -e @.statistics.tx_bytes` rx_bytes_after=`ubus call network.device status "{'name':'$interface'}" | jsonfilter -e @.statistics.rx_bytes` rh=`cat ${DOWNLOAD_DIAGNOSTIC_LOG_FILE} | grep "resolve host"` [ -n "$ba" ] && { $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=Error_CannotResolveHostName; kill $PID 2> /dev/null; return; } ba=`echo "$res" | grep "bad address"` [ -n "$ba" ] && { $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=Error_InitConnectionFailed; kill $PID 2> /dev/null; return; } stc=`cat ${DOWNLOAD_DIAGNOSTIC_LOG_FILE} | grep "404 Not Found"` [ -n "$stc" ] && { $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=Error_NoResponse; kill $PID 2> /dev/null; return; } stc=`cat ${DOWNLOAD_DIAGNOSTIC_LOG_FILE} | grep "100%"` [ -z "$stc" ] && { $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=Error_TransferFailed; kill $PID 2> /dev/null; return; } fi tx_bytes=$((tx_bytes_after-tx_bytes_before)) rx_bytes=$((rx_bytes_after-rx_bytes_before)) periodtime=$(($((time2-time1))*1000000)) $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=Completed $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].TotalBytesReceived=$rx_bytes $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].TotalBytesSent=$tx_bytes $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].PeriodOfFullLoading=$periodtime local perconnection=`$UCI_GET_VARSTATE cwmp.@downloaddiagnostic[0].EnablePerConnection` if ([ "$perconnection" == "true" ] || [ "$perconnection" == "1" ]); then $UCI_ADD_VARSTATE cwmp DownloadPerConnection $UCI_SET_VARSTATE cwmp.@DownloadPerConnection[0].TotalBytesReceived=$rx_bytes $UCI_SET_VARSTATE cwmp.@DownloadPerConnection[0].TotalBytesSent=$tx_bytes else $UCI_DELETE_VARSTATE cwmp.@DownloadPerConnection[0] fi rm ${DOWNLOAD_DIAGNOSTIC_FILE} 2>/dev/null rm ${DOWNLOAD_DIAGNOSTIC_LOG_FILE} 2>/dev/null sleep 1 local pids=`ps | grep $PID` kill $PID &>/dev/null # Enable acceleration on Broadcom devices after killing the tcpdump pid [ -e /usr/sbin/fcctl ] && { fcctl enable >/dev/null 2>&1; fcctl flush >/dev/null 2>&1; } } download_stop_diagnostic() { $UCI_DELETE_VARSTATE cwmp.@DownloadPerConnection[0] local pids=`ps | grep download_launch.*run | grep -v grep | awk '{print $1}'` if [ -n "$pids" ]; then kill -9 $pids &>/dev/null $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=None fi local pids=`ps | grep download_launch.*run | grep -v grep | awk '{print $1}'` if [ -n "$pids" ]; then kids=$(grep -l "PPid.*$pids" /proc/*/task/*/status | grep -o "[0-9]*") for kid in $kids; do kill -9 $kid &>/dev/null done kill -9 $pids &>/dev/null $UCI_SET_VARSTATE cwmp.@downloaddiagnostic[0].DiagnosticState=None fi } if [ "$1" == "run" ] ; then download_launch $2 $3 $4 elif [ "$1" == "stop" ]; then download_stop_diagnostic else return fi