QuecManager v2.3.2 Release Candidate

This commit is contained in:
Russel Yasol
2025-09-07 18:36:18 +08:00
parent 64f06fc056
commit 08a1cd8d7b
88 changed files with 800 additions and 456 deletions

View File

@@ -2,10 +2,10 @@
# AT Queue Client for OpenWRT
# Located in /www/cgi-bin/services/at_queue_client
AUTH_FILE="/tmp/auth_success"
QUEUE_DIR="/tmp/at_queue"
RESULTS_DIR="$QUEUE_DIR/results"
QUEUE_MANAGER="/www/cgi-bin/services/at_queue_manager.sh"
HOST_DIR=$(pwd)
QUEUE_MANAGER="${HOST_DIR}/cgi-bin/services/at_queue_manager.sh"
POLL_INTERVAL=0.01
usage() {
@@ -27,15 +27,13 @@ output_json() {
# URL decode function
urldecode() {
local encoded="$1"
logger -t at_queue -p daemon.debug "urldecode: input='$encoded'"
# Handle %2B -> + and %22 -> " conversions
local decoded="${encoded//%2B/+}"
decoded="${decoded//%22/\"}"
# Then handle other encoded characters
decoded=$(printf '%b' "${decoded//%/\\x}")
logger -t at_queue -p daemon.debug "urldecode: output='$decoded'"
echo "$decoded"
}
@@ -43,28 +41,28 @@ urldecode() {
get_command_id() {
local response="$1"
echo "DEBUG: Raw response: '$response'" >&2
# Strip any headers from response
local json_response=$(echo "$response" | sed -n '/^{/,$p')
echo "DEBUG: JSON portion: '$json_response'" >&2
# Try to extract command_id using grep and sed instead of jsonfilter
local cmd_id=$(echo "$json_response" | grep -o '"command_id":"[^"]*"' | sed 's/"command_id":"//;s/"$//')
if [ -n "$cmd_id" ]; then
echo "$cmd_id"
return 0
fi
# Fallback to jsonfilter if available
echo "DEBUG: Trying jsonfilter as fallback" >&2
local cmd_id_jsonfilter=$(echo "$json_response" | jsonfilter -e '@.command_id' 2>/dev/null)
if [ -n "$cmd_id_jsonfilter" ]; then
echo "$cmd_id_jsonfilter"
return 0
fi
echo "ERROR: Failed to extract command ID from response" >&2
return 1
}
@@ -72,20 +70,16 @@ get_command_id() {
# Normalize AT command
normalize_at_command() {
local cmd="$1"
logger -t at_queue -p daemon.debug "normalize: input='$cmd'"
# URL decode the command
cmd=$(urldecode "$cmd")
logger -t at_queue -p daemon.debug "normalize: after urldecode='$cmd'"
# Remove any carriage returns or newlines
cmd=$(echo "$cmd" | tr -d '\r\n')
logger -t at_queue -p daemon.debug "normalize: after cleanup='$cmd'"
# Trim leading/trailing whitespace while preserving quotes
cmd=$(echo "$cmd" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
logger -t at_queue -p daemon.debug "normalize: final output='$cmd'"
echo "$cmd"
}
@@ -93,12 +87,12 @@ normalize_at_command() {
submit_command() {
local cmd="$1"
local priority=10
# Set high priority for QSCAN commands for faster processing
if echo "$cmd" | grep -qi "AT+QSCAN"; then
priority=1
fi
# Submit using appropriate method
if [ "${SCRIPT_NAME}" != "" ]; then
# CGI mode - direct execution
@@ -114,11 +108,10 @@ submit_command() {
check_result() {
local cmd_id="$1"
local show_headers="${2:-1}" # Add parameter for header control
if [ -f "$RESULTS_DIR/$cmd_id.json" ]; then
local result_content=$(cat "$RESULTS_DIR/$cmd_id.json")
if [ -z "$result_content" ]; then
logger -t at_queue -p daemon.error "Empty result file for command ID: $cmd_id"
local error_json="{\"error\":\"Empty result file\",\"command_id\":\"$cmd_id\"}"
output_json "$error_json" "$show_headers"
return 1
@@ -137,37 +130,37 @@ wait_for_completion() {
local timeout="$2"
local show_headers="${3:-1}"
local result_file="$RESULTS_DIR/$cmd_id.json"
if [ -z "$cmd_id" ]; then
local error_json="{\"error\":\"Invalid command ID\"}"
output_json "$error_json" "$show_headers"
return 1
fi
# First quick check
if [ -f "$result_file" ]; then
output_json "$(cat "$result_file")" "$show_headers"
return 0
fi
# Wait with shorter polling interval
local start_time=$(date +%s)
local current_time
while true; do
if [ -f "$result_file" ]; then
output_json "$(cat "$result_file")" "$show_headers"
return 0
fi
current_time=$(date +%s)
if [ $((current_time - start_time)) -ge "$timeout" ]; then
break
fi
sleep $POLL_INTERVAL
done
local error_json=$(cat << EOF
{
"error": "Timeout waiting for completion",
@@ -183,33 +176,19 @@ EOF
# CGI request handling
if [ "${SCRIPT_NAME}" != "" ]; then
# Output headers only once at the beginning
echo "Content-Type: application/json"
echo "Content-Type: application/json"
echo ""
# Get Token from Authorization Header
TOKEN="${HTTP_AUTHORIZATION}"
if [ ! -f $AUTH_FILE ]; then
output_json "{\"error\":\"Unauthenticated Request\"}" "0"
# Check for Authorization Header
if [ -z "${HTTP_AUTHORIZATION}" ]; then
output_json "{\"error\":\"Unauthorized\"}" "0"
exit 1
fi
if [ -z "$TOKEN" ] || "${TOKEN}" = "" || [ $(grep "${TOKEN}" "${AUTH_FILE}" | wc -l) -eq 0 ]; then
output_json "{\"response\": { \"status\": \"error\", \"raw_output\": \"Not Authorized\" }, \"command\": {\"timestamp\": \"$(date +%Y%m%d'T'%H%M%S)\"}, \"error\":\"Not Authorized\"}" "0"
exit 1
fi
# Check if token is within 2 hours
TOKEN_LINE=$(grep "${TOKEN}" "${AUTH_FILE}")
TOKEN_DATE=$(echo "$TOKEN_LINE" | awk '{print $1}' | sed 's/T/ /')
TOKEN_TIME=$(date -d "$TOKEN_DATE" +%s 2>/dev/null)
NOW_TIME=$(date +%s)
MAX_AGE=$((2 * 3600)) # 2 hours in seconds
if [ -z "$TOKEN_TIME" ] || [ $((NOW_TIME - TOKEN_TIME)) -gt $MAX_AGE ]; then
output_json "{ \"response\": { \"status\": \"error\", \"raw_output\": \"Token expired. Reauthenticate to get new token.\" }, \"command\": {\"timestamp\": \"$(date +%Y%m%d'T'%H%M%S)\"}, \"error\":\"Token expired\"}" "0"
# Cleanup/Remove token from file
sed -i -e "s/.*${TOKEN}.*//g" /tmp/auth_success 2>/dev/null
exit 1
AUTH_RESPONSE=$(/bin/sh ${HOST_DIR}/cgi-bin/quecmanager/auth-token.sh process "${HTTP_AUTHORIZATION}")
AUTH_RESPONSE_STATUS=$?
if [ $AUTH_RESPONSE_STATUS -ne 0 ]; then
output_json $AUTH_RESPONSE "0"
exit $AUTH_RESPONSE_STATUS
fi
# Parse query string

View File

@@ -0,0 +1,84 @@
#!/bin/sh
# Exit Codes: 0 = Success, 1 = Not Authorized, 2 = Auth File Not Found, 3 = Token Removal Failed
EXIT_CODE=0
AUTH_FILE="/tmp/quecmanager/auth_success"
cleanup() {
MAX_AGE=$((2 * 3600)) # 2 hours in seconds
NOW_TIME=$(date +%s)
TMP_FILE=$(mktemp)
# AUTH_FILE cleanup process, Remove any token lines older than 2 hours from AUTH_FILE
if [ -f $AUTH_FILE ]; then
while read -r line; do
if [ -n "$(echo "$line" | tr -d '[:space:]')" ]; then
# Extract the date from the line and convert it to a timestamp
TOKEN_DATE=$(echo "$line" | awk '{print $1}' | sed 's/T/ /')
TOKEN_TIME=$(date -d "$TOKEN_DATE" +%s 2>/dev/null)
# If date is valid and not older than MAX_AGE, keep the line
if [ -n "$TOKEN_TIME" ] && [ $((NOW_TIME - TOKEN_TIME)) -le $MAX_AGE ]; then
echo "$line" >> "$TMP_FILE"
fi
fi
done < "$AUTH_FILE"
mv "$TMP_FILE" "$AUTH_FILE"
fi
}
removeToken() {
TOKEN=$1
# Remove token from file
if [ -f $AUTH_FILE ] && [ -n "${TOKEN}" ]; then
sed -i -e "s/.*${TOKEN}.*//g" ${AUTH_FILE} 2>/dev/null
echo '{"state":"success", "message":"Logged out successfully"}'
EXIT_CODE=0
else
echo '{"state":"failed", "message":"Token Removal Failed"}'
EXIT_CODE=3
fi
}
process() {
if [ -n "$1" ]; then
TOKEN=$1
else
TOKEN=$(head -c 16 /dev/urandom | hexdump -v -e '/1 "%02x"')
touch ${AUTH_FILE}
echo "$(date +"%Y-%m-%dT%H:%M:%S") ${TOKEN}" >> ${AUTH_FILE}
echo "" >> ${AUTH_FILE}
fi
if [ ! -f $AUTH_FILE ]; then
echo '{"state":"failed", "message":"Authentication file not found"}'
EXIT_CODE=2
fi
if [ $EXIT_CODE -eq 0 ] && ( [ -z "$TOKEN" ] || [ "$TOKEN" = "" ] || [ $(grep "${TOKEN}" "${AUTH_FILE}" | wc -l) -eq 0 ] ); then
echo "{\"response\": { \"status\": \"error\", \"raw_output\": \"Not Authorized\" }, \"command\": {\"timestamp\": \"$(date +%Y%m%d'T'%H%M%S)\"}, \"error\":\"Not Authorized\"}"
EXIT_CODE=1
fi
if [ $EXIT_CODE -eq 0 ] && grep -q "$TOKEN" "$AUTH_FILE"; then
echo "{\"state\":\"success\", \"token\":\"$TOKEN\"}"
EXIT_CODE=0
fi
}
case $1 in
removeToken)
removeToken $2
;;
cleanup)
cleanup
;;
process)
cleanup
process $2
;;
*)
cleanup
process $1
;;
esac
exit $EXIT_CODE

View File

@@ -7,12 +7,11 @@ echo ""
# Read POST data
read -r POST_DATA
# Debug log for generated hash
DEBUG_LOG="/tmp/auth.log"
AUTH_FILE="/tmp/auth_success"
# Extract the password from POST data (URL encoded)
USER="root"
INPUT_PASSWORD=$(echo "$POST_DATA" | grep -o 'password=[^&]*' | cut -d= -f2-)
RESPONSE=""
HOST_DIR=$(pwd)
# URL-decode the password while preserving most special characters
# First decode percent-encoded sequences
@@ -51,46 +50,13 @@ SALT=$(echo "$USER_HASH" | cut -d'$' -f3)
# Use printf to avoid issues with special characters in echo
GENERATED_HASH=$(printf '%s' "$INPUT_PASSWORD" | openssl passwd -1 -salt "$SALT" -stdin)
# Log generated hash for debugging
printf "Generated hash: %s\n" "$GENERATED_HASH" >> "$DEBUG_LOG"
# Check if the request for AUTH contains the Authorization Header so as to assure we're not at an initial login
SUPPLIED_TOKEN="${HTTP_AUTHORIZATION}"
# Compare the generated hash with the one in the shadow file
if [ "$GENERATED_HASH" = "$USER_HASH" ]; then
# If the token is supplied, use it; otherwise, generate a new one and store it in the auth file
if [ "$SUPPLIED_TOKEN" != "" ]; then
TOKEN="$SUPPLIED_TOKEN"
else
TOKEN=$(head -c 16 /dev/urandom | hexdump -v -e '/1 "%02x"')
CREATED_DATE=$(date +"%Y-%m-%dT%H:%M:%S")
touch ${AUTH_FILE}
echo "${CREATED_DATE} ${TOKEN}" >> ${AUTH_FILE}
echo "" >> ${AUTH_FILE}
fi
echo "{\"state\":\"success\",\"token\":\"${TOKEN}\"}"
RESPONSE=$(/bin/sh ${HOST_DIR}/cgi-bin/quecmanager/auth-token.sh process "$SUPPLIED_TOKEN")
else
# Remove token from file
if [ -n ${TOKEN} ]; then
sed -i -e "s/.*${TOKEN}.*//g" ${AUTH_FILE} 2>/dev/null
fi
echo '{"state":"failed", "message":"Authentication failed"}'
RESPONSE=$(/bin/sh ${HOST_DIR}/cgi-bin/quecmanager/auth-token.sh removeToken "$SUPPLIED_TOKEN")
fi
# AUTH_FILE cleanup process, Remove any token lines older than 2 hours from AUTH_FILE
MAX_AGE=$((2 * 3600)) # 2 hours in seconds
NOW_TIME=$(date +%s)
TMP_FILE=$(mktemp)
while read -r line; do
if [ -n "$(echo "$line" | tr -d '[:space:]')" ]; then
# Extract the date from the line and convert it to a timestamp
TOKEN_DATE=$(echo "$line" | awk '{print $1}' | sed 's/T/ /')
TOKEN_TIME=$(date -d "$TOKEN_DATE" +%s 2>/dev/null)
# If date is valid and not older than MAX_AGE, keep the line
if [ -n "$TOKEN_TIME" ] && [ $((NOW_TIME - TOKEN_TIME)) -le $MAX_AGE ]; then
echo "$line" >> "$TMP_FILE"
fi
fi
done < "$AUTH_FILE"
mv "$TMP_FILE" "$AUTH_FILE"
echo "$RESPONSE"

View File

@@ -0,0 +1,303 @@
#!/bin/sh
# OpenWrt-Compatible Improved fetch_data.sh
# Optimized for OpenWrt/BusyBox environment with enhanced performance
# Set content-type for JSON response
printf "Content-type: application/json\r\n"
printf "\r\n"
# Load centralized logging
. /www/cgi-bin/services/quecmanager_logger.sh
# Configuration
QUEUE_DIR="/tmp/at_queue"
QUEUE_MANAGER="/www/cgi-bin/services/at_queue_manager.sh"
SCRIPT_NAME_LOG="fetch_data"
# Performance settings - OpenWrt optimized
BATCH_TIMEOUT=45 # Timeout for batch operations
INDIVIDUAL_TIMEOUT=15 # Timeout for individual commands
TOKEN_RETRY_LIMIT=8 # Reduced retries for faster failure
TOKEN_RETRY_DELAY=0.1 # Faster retry intervals
# Minimal logging for performance
log_fetch() {
local level="$1"
local message="$2"
# Only log errors to centralized system for performance
case "$level" in
"error")
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
;;
"debug")
[ "${DEBUG_MODE:-0}" = "1" ] && logger -t fetch_data -p "daemon.debug" "$message"
;;
esac
}
# Ensure queue directory exists
mkdir -p "$QUEUE_DIR"
# OpenWrt-compatible JSON escaping using shell builtins
escape_json() {
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\x1b/\\u001b/g' | tr -d '\r\n\f\b'
}
# OpenWrt-compatible URL encoding
urlencode_simple() {
local string="$1"
# Encode most common special characters for BusyBox compatibility
string="${string// /%20}"
string="${string//+/%2B}"
string="${string//\"/%22}"
string="${string//=/%3D}"
string="${string//&/%26}"
string="${string//#/%23}"
string="${string//?/%3F}"
string="${string//;/%3B}"
string="${string//,/%2C}"
echo "$string"
}
# Fast AT command execution with OpenWrt timeout handling
execute_at_command() {
local cmd="$1"
local timeout="${2:-$INDIVIDUAL_TIMEOUT}"
local output=""
local status=1
# OpenWrt-compatible timeout implementation
if command -v timeout >/dev/null 2>&1; then
# Use timeout command if available
output=$(timeout "$timeout" sms_tool at "$cmd" 2>&1)
status=$?
else
# BusyBox-compatible timeout implementation
(
sms_tool at "$cmd" 2>&1 &
local cmd_pid=$!
# Background timeout
(sleep "$timeout" && kill -TERM $cmd_pid 2>/dev/null) &
local timeout_pid=$!
wait $cmd_pid
local cmd_status=$?
kill $timeout_pid 2>/dev/null
exit $cmd_status
)
status=$?
output=$(cat)
fi
if [ $status -eq 0 ] && [ -n "$output" ]; then
echo "$output"
return 0
fi
return 1
}
# Intelligent command grouping for batch processing
group_commands() {
local commands="$1"
# Separate quick vs slow commands for optimized processing
local quick_commands=""
local slow_commands=""
for cmd in $commands; do
case "$cmd" in
*"?"*|*"CREG"*|*"CGREG"*|*"CEREG"*|*"CPIN"*|*"CFUN"*)
quick_commands="$quick_commands $cmd"
;;
*)
slow_commands="$slow_commands $cmd"
;;
esac
done
# Process quick commands first with shorter timeout
if [ -n "$quick_commands" ]; then
process_command_batch "$quick_commands" 10
fi
# Then process slower commands
if [ -n "$slow_commands" ]; then
process_command_batch "$slow_commands" $INDIVIDUAL_TIMEOUT
fi
}
# Process a batch of commands using the queue manager
process_command_batch() {
local commands="$1"
local timeout="${2:-$INDIVIDUAL_TIMEOUT}"
local first=1
for cmd in $commands; do
[ $first -eq 0 ] && printf ','
first=0
# Use queue manager for better performance and queuing
local escaped_cmd=$(urlencode_simple "$cmd")
local priority=5 # Medium priority for batch operations
# Submit to queue manager
local response=$(REQUEST_METHOD="GET" QUERY_STRING="command=$escaped_cmd&priority=$priority&timeout=$timeout" "$QUEUE_MANAGER" 2>/dev/null)
# Extract command ID
local cmd_id=""
if [ -n "$response" ]; then
cmd_id=$(echo "$response" | grep -o '"command_id":"[^"]*"' | cut -d'"' -f4)
[ -z "$cmd_id" ] && cmd_id=$(echo "$response" | grep -o '"id":"[^"]*"' | cut -d'"' -f4)
fi
local escaped_cmd_display=$(escape_json "$cmd")
if [ -n "$cmd_id" ]; then
# Wait for result with polling
local result_file="/tmp/at_queue/results/$cmd_id"
local wait_time=0
local max_wait=$timeout
while [ $wait_time -lt $max_wait ]; do
if [ -f "$result_file" ]; then
local result_content=$(cat "$result_file" 2>/dev/null)
if [ -n "$result_content" ]; then
# Extract response from result
local cmd_response=$(echo "$result_content" | grep -o '"response":"[^"]*"' | cut -d'"' -f4)
local cmd_status=$(echo "$result_content" | grep -o '"status":"[^"]*"' | cut -d'"' -f4)
if [ "$cmd_status" = "success" ] && [ -n "$cmd_response" ]; then
printf '{"command":"%s","response":"%s","status":"success"}' \
"$escaped_cmd_display" "$(escape_json "$cmd_response")"
else
printf '{"command":"%s","response":"Command failed","status":"error"}' \
"$escaped_cmd_display"
fi
# Cleanup result file
rm -f "$result_file" 2>/dev/null
break
fi
fi
sleep 0.2
wait_time=$((wait_time + 1))
done
# If we didn't get a result, report timeout
if [ $wait_time -ge $max_wait ]; then
printf '{"command":"%s","response":"Command timed out","status":"timeout"}' \
"$escaped_cmd_display"
rm -f "$result_file" 2>/dev/null
fi
else
# Direct execution fallback if queue manager fails
local output=$(execute_at_command "$cmd" "$timeout")
local cmd_status=$?
if [ $cmd_status -eq 0 ] && [ -n "$output" ]; then
printf '{"command":"%s","response":"%s","status":"success"}' \
"$escaped_cmd_display" "$(escape_json "$output")"
else
printf '{"command":"%s","response":"Direct execution failed","status":"error"}' \
"$escaped_cmd_display"
fi
fi
done
}
# Enhanced batch processing with optimizations
process_all_commands() {
local commands="$1"
local priority="${2:-5}"
printf '['
group_commands "$commands"
printf ']\r\n'
return 0
}
# Cleanup on exit
cleanup() {
exit 0
}
# Set up signal handlers
trap cleanup INT TERM
# Enhanced command sets with better organization
COMMAND_SET_1='AT+QUIMSLOT? AT+CNUM AT+COPS? AT+CIMI AT+ICCID AT+CGSN AT+CPIN? AT+CGDCONT? AT+CREG? AT+CFUN? AT+QENG="servingcell" AT+QTEMP AT+CGCONTRDP'
COMMAND_SET_2='AT+QCAINFO=1;+QCAINFO;+QCAINFO=0 AT+QRSRP AT+QMAP="WWAN" AT+C5GREG=2;+C5GREG? AT+CGREG=2;+CGREG? AT+QRSRQ AT+QSINR'
COMMAND_SET_3='AT+CGMI AT+CGMM AT+QGMR AT+CNUM AT+CIMI AT+ICCID AT+CGSN AT+QMAP="LANIP" AT+QMAP="WWAN" AT+QGETCAPABILITY'
COMMAND_SET_4='AT+QMAP="MPDN_RULE" AT+QMAP="DHCPV4DNS" AT+QCFG="usbnet" AT+QNWCFG="3gpp_rel"'
COMMAND_SET_5='AT+QRSRP AT+QRSRQ AT+QSINR AT+QCAINFO AT+QSPN'
COMMAND_SET_6='AT+CEREG=2;+CEREG? AT+C5GREG=2;+C5GREG? AT+CPIN? AT+CGDCONT? AT+CGCONTRDP AT+QMAP="WWAN" AT+QRSRP AT+QTEMP'
COMMAND_SET_7='AT+QNWPREFCFG="policy_band" AT+QNWPREFCFG="lte_band";+QNWPREFCFG="nsa_nr5g_band";+QNWPREFCFG="nr5g_band"'
COMMAND_SET_8='AT+QNWLOCK="common/4g" AT+QNWLOCK="common/5g" AT+QNWLOCK="save_ctrl"'
COMMAND_SET_9='AT+QNWCFG="lte_time_advance",1;+QNWCFG="lte_time_advance" AT+QNWCFG="nr5g_time_advance",1;+QNWCFG="nr5g_time_advance"'
COMMAND_SET_10='AT+QNWPREFCFG="mode_pref" AT+QNWPREFCFG="nr5g_disable_mode" AT+QMBNCFG="AutoSel" AT+QMBNCFG="list"'
# Parse command set with validation - OpenWrt compatible
COMMAND_SET=$(echo "$QUERY_STRING" | grep -o 'set=[0-9]\+' | cut -d'=' -f2 | tr -cd '0-9')
if [ -z "$COMMAND_SET" ] || [ "$COMMAND_SET" -lt 1 ] || [ "$COMMAND_SET" -gt 10 ]; then
COMMAND_SET=1
fi
# Select appropriate command set
case "$COMMAND_SET" in
1) COMMANDS="$COMMAND_SET_1" ;;
2) COMMANDS="$COMMAND_SET_2" ;;
3) COMMANDS="$COMMAND_SET_3" ;;
4) COMMANDS="$COMMAND_SET_4" ;;
5) COMMANDS="$COMMAND_SET_5" ;;
6) COMMANDS="$COMMAND_SET_6" ;;
7) COMMANDS="$COMMAND_SET_7" ;;
8) COMMANDS="$COMMAND_SET_8" ;;
9) COMMANDS="$COMMAND_SET_9" ;;
10) COMMANDS="$COMMAND_SET_10" ;;
esac
# Set priority based on command type
PRIORITY=5 # Medium-high priority for data fetching
# Check for high priority commands
if echo "$COMMANDS" | grep -qi "QSCAN"; then
PRIORITY=1
elif echo "$COMMANDS" | grep -qi "COPS\|CFUN"; then
PRIORITY=3
fi
# Execute batch processing with timeout protection
(
# Set overall timeout for the entire script using OpenWrt-compatible method
if command -v timeout >/dev/null 2>&1; then
timeout $BATCH_TIMEOUT sh -c '
process_all_commands "$1" "$2"
' _ "$COMMANDS" "$PRIORITY"
else
# BusyBox timeout fallback
(
process_all_commands "$COMMANDS" "$PRIORITY" &
local main_pid=$!
(sleep $BATCH_TIMEOUT && kill -TERM $main_pid 2>/dev/null) &
local timeout_pid=$!
wait $main_pid
local exit_status=$?
kill $timeout_pid 2>/dev/null
if [ $exit_status -eq 143 ] || [ $exit_status -eq 124 ]; then
printf '[{"command":"batch","response":"Script execution timed out","status":"timeout"}]\r\n'
fi
)
fi
) || {
# Handle script timeout
printf '[{"command":"batch","response":"Script execution timed out","status":"timeout"}]\r\n'
}

View File

@@ -1,10 +0,0 @@
#!/bin/sh
echo "Content-Type: application/json"
echo "Cache-Control: no-cache, no-store, must-revalidate"
echo "Pragma: no-cache"
echo "Expires: 0"
echo ""
# Basic response indicating the server is up
echo '{"alive": true}'

View File

@@ -1,8 +1,9 @@
#!/bin/sh
# Get token from Request Header Authorization
USER_TOKEN="${HTTP_AUTHORIZATION}"
# Remove token from file
sed -i -e "s/.*${USER_TOKEN}.*//g" /tmp/auth_success 2>/dev/null
HOST_DIR=$(pwd)
AUTH_RESPONSE=$(/bin/sh ${HOST_DIR}/cgi-bin/quecmanager/auth-token.sh removeToken "${HTTP_AUTHORIZATION}")
EXIT_CODE=$?
echo "Content-Type: application/json"
echo "Cache-Control: no-cache, no-store, must-revalidate"
@@ -12,4 +13,5 @@ echo ""
echo '{"state":"success", "message":"Logged out successfully"}'
echo $AUTH_RESPONSE
exit $EXIT_CODE

View File

@@ -4,38 +4,18 @@
echo "Content-type: application/json"
echo ""
TOKEN="${HTTP_AUTHORIZATION}"
# Read POST data
read -r POST_DATA
# Debug log for generated hash
DEBUG_LOG="/tmp/password_change.log"
AUTH_FILE="/tmp/auth_success"
HOST_DIR=$(pwd)
# Get Token from Authorization Header on Request
if [ ! -f $AUTH_FILE ]; then
echo "{\"error\":\"Unauthenticated Request\"}"
exit 1
fi
if [ -z "$TOKEN" ] || "${TOKEN}" = "" || [ $(grep "${TOKEN}" "${AUTH_FILE}" | wc -l) -eq 0 ]; then
echo "{\"response\": { \"status\": \"error\", \"raw_output\": \"Not Authorized\" }, \"command\": {\"timestamp\": \"$(date +%Y%m%d'T'%H%M%S)\"}, \"error\":\"Not Authorized\"}"
exit 1
fi
# Check if token is within 2 hours
TOKEN_LINE=$(grep "${TOKEN}" "${AUTH_FILE}")
TOKEN_DATE=$(echo "$TOKEN_LINE" | awk '{print $1}' | sed 's/T/ /')
TOKEN_TIME=$(date -d "$TOKEN_DATE" +%s 2>/dev/null)
NOW_TIME=$(date +%s)
MAX_AGE=$((2 * 3600)) # 2 hours in seconds
if [ -z "$TOKEN_TIME" ] || [ $((NOW_TIME - TOKEN_TIME)) -gt $MAX_AGE ]; then
echo "{ \"response\": { \"status\": \"error\", \"raw_output\": \"Token expired. Reauthenticate to get new token.\" }, \"command\": {\"timestamp\": \"$(date +%Y%m%d'T'%H%M%S)\"}, \"error\":\"Token expired\"}"
# Cleanup/Remove token from file
sed -i -e "s/.*${TOKEN}.*//g" /tmp/auth_success 2>/dev/null
exit 1
AUTH_RESPONSE=$(/bin/sh ${HOST_DIR}/cgi-bin/quecmanager/auth-token.sh process "$HTTP_AUTHORIZATION")
AUTH_RESPONSE_STATUS=$?
if [ $AUTH_RESPONSE_STATUS -ne 0 ]; then
echo $AUTH_RESPONSE
exit $AUTH_RESPONSE_STATUS
fi

View File

@@ -1,9 +1,9 @@
#!/bin/sh
# Ping Settings Configuration Script
# Manages ping service (enable/disable) and daemon settings
# Manages ping service (enable/disable) and daemon settings with dynamic service management
# Author: dr-dolomite
# Date: 2025-08-04
# Date: 2025-08-31
# Handle OPTIONS request first (before any headers)
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
@@ -29,9 +29,7 @@ CONFIG_FILE="$CONFIG_DIR/ping_settings.conf"
FALLBACK_CONFIG_DIR="/tmp/quecmanager/settings"
FALLBACK_CONFIG_FILE="$FALLBACK_CONFIG_DIR/ping_settings.conf"
LOG_FILE="/tmp/ping_settings.log"
PID_FILE="/tmp/quecmanager/ping_daemon.pid"
# Prefer the new services location, fall back to the legacy path for compatibility
DAEMON_RELATIVE_PATHS="/cgi-bin/services/ping_daemon.sh"
SERVICES_INIT="/etc/init.d/quecmanager_services"
# Logging function
log_message() {
@@ -72,77 +70,9 @@ resolve_config_for_read() {
return 0
}
# Determine daemon path (absolute) based on typical web root layouts
resolve_daemon_path() {
# Common locations where CGI/WWW is mounted
for rel in $DAEMON_RELATIVE_PATHS; do
for base in \
/www \
/; do
if [ -x "$base$rel" ]; then
echo "$base$rel"
return 0
fi
done
# Also try as-is if busybox httpd cwd matches web root
if [ -x "$rel" ]; then
echo "$rel"
return 0
fi
done
# Nothing found; return first candidate as a best-effort path
set -- $DAEMON_RELATIVE_PATHS
echo "$1"
}
daemon_running() {
if [ -f "$PID_FILE" ]; then
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
return 0
fi
fi
return 1
}
start_daemon() {
# Ensure /tmp/quecmanager exists for PID
[ -d "/tmp/quecmanager" ] || mkdir -p "/tmp/quecmanager"
if daemon_running; then
log_message "Daemon already running"
return 0
fi
local daemon_path
daemon_path="$(resolve_daemon_path)"
if [ ! -x "$daemon_path" ]; then
# Try to make it executable if present
if [ -f "$daemon_path" ]; then
chmod +x "$daemon_path" 2>/dev/null || true
fi
fi
if [ -x "$daemon_path" ]; then
nohup "$daemon_path" >/dev/null 2>&1 &
log_message "Started ping daemon: $daemon_path (pid $!)"
return 0
else
log_message "Daemon script not found or not executable: $daemon_path"
return 1
fi
}
stop_daemon() {
if daemon_running; then
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
if [ -n "${pid:-}" ]; then
kill "$pid" 2>/dev/null || true
sleep 0.2
kill -9 "$pid" 2>/dev/null || true
fi
fi
rm -f "$PID_FILE" 2>/dev/null || true
# Check if ping daemon is running
is_ping_daemon_running() {
pgrep -f "ping_daemon.sh" >/dev/null 2>&1
}
# Get current ping setting
@@ -202,6 +132,117 @@ save_config() {
log_message "Saved ping config (fallback): enabled=$enabled host=$host interval=$interval"
}
# Add ping daemon to services init script (remove the static version and add dynamic version)
add_ping_daemon_to_services() {
if [ ! -f "$SERVICES_INIT" ]; then
log_message "Services init file not found: $SERVICES_INIT"
return 1
fi
# First, remove any existing ping daemon block (both static and dynamic)
remove_ping_daemon_from_services
# Add the dynamic ping daemon block before "All QuecManager services Started"
local temp_file="/tmp/services_temp_$$"
awk '
/echo "All QuecManager services Started"/ {
print " # Start ping daemon"
print " echo \"Starting Ping Daemon...\""
print " procd_open_instance"
print " procd_set_param command /www/cgi-bin/services/ping_daemon.sh"
print " procd_set_param respawn"
print " procd_set_param stdout 1"
print " procd_set_param stderr 1"
print " procd_close_instance"
print " echo \"Ping Daemon started\""
print ""
}
{ print }
' "$SERVICES_INIT" > "$temp_file"
if [ -s "$temp_file" ]; then
mv "$temp_file" "$SERVICES_INIT"
chmod +x "$SERVICES_INIT"
log_message "Added ping daemon to services init script"
return 0
else
rm -f "$temp_file"
log_message "Failed to add ping daemon to services"
return 1
fi
}
# Remove ping daemon from services init script (both static and dynamic versions)
remove_ping_daemon_from_services() {
if [ ! -f "$SERVICES_INIT" ]; then
log_message "Services init file not found: $SERVICES_INIT"
return 1
fi
local temp_file="/tmp/services_temp_$$"
# Remove both the old static ping daemon block and any dynamic ping daemon block
awk '
# Skip the old static ping daemon block
/# Start ping daemon if enabled in configuration/ {
skip_static=1
next
}
skip_static && /echo "Ping Daemon started"/ {
skip_static=0
next
}
skip_static && /echo "Ping configuration not found/ {
skip_static=0
next
}
skip_static { next }
# Skip the new dynamic ping daemon block
/# Start ping daemon$/ {
skip_dynamic=1
next
}
skip_dynamic && /^$/ {
skip_dynamic=0
next
}
skip_dynamic { next }
# Print everything else
!skip_static && !skip_dynamic { print }
' "$SERVICES_INIT" > "$temp_file"
if [ -s "$temp_file" ]; then
mv "$temp_file" "$SERVICES_INIT"
chmod +x "$SERVICES_INIT"
log_message "Removed ping daemon from services init script"
return 0
else
rm -f "$temp_file"
log_message "Failed to remove ping daemon from services"
return 1
fi
}
# Restart QuecManager services
restart_services() {
log_message "Restarting QuecManager services..."
# Stop services
if [ -x "$SERVICES_INIT" ]; then
"$SERVICES_INIT" stop >/dev/null 2>&1
sleep 2
"$SERVICES_INIT" start >/dev/null 2>&1
log_message "Services restarted successfully"
return 0
else
log_message "Cannot restart services - init script not found or not executable"
return 1
fi
}
# Delete ping configuration (reset to default)
delete_ping_setting() {
local removed=1
@@ -223,7 +264,7 @@ handle_get() {
log_message "GET request received"
get_config_values
local running=false
if daemon_running; then running=true; fi
if is_ping_daemon_running; then running=true; fi
local is_default=true
if [ -f "$CONFIG_FILE" ] && grep -q "^PING_ENABLED=" "$CONFIG_FILE"; then
is_default=false
@@ -264,35 +305,34 @@ handle_post() {
send_error "INVALID_INTERVAL" "Interval must be between 1 and 3600 seconds."
fi
# Capture previous values to decide on restart
# Get current config to compare
get_config_values
local prev_enabled="$ENABLED"
local prev_host="$HOST"
local prev_interval="$INTERVAL"
# Save new configuration
save_config "$enabled" "$host" "$interval" || send_error "WRITE_FAILED" "Failed to save configuration"
# Handle service changes using dynamic management like memory
if [ "$enabled" = "true" ]; then
if daemon_running; then
# Restart only if effective parameters changed
if [ "$prev_host" != "$host" ] || [ "$prev_interval" != "$interval" ] || [ "$prev_enabled" != "$enabled" ]; then
log_message "Config change detected (host/interval/enabled). Restarting daemon."
stop_daemon
start_daemon || log_message "Failed to restart daemon"
else
log_message "No change requiring restart; daemon remains running"
fi
else
start_daemon || log_message "Failed to start daemon"
# Enable ping daemon
add_ping_daemon_to_services
if [ "$prev_enabled" != "true" ] || [ "$prev_host" != "$host" ] || [ "$prev_interval" != "$interval" ]; then
restart_services
fi
else
stop_daemon
# Disable ping daemon
remove_ping_daemon_from_services
restart_services
fi
get_config_values
# Return current status
sleep 1 # Give services time to start/stop
local running=false
if daemon_running; then running=true; fi
send_success "Ping setting updated successfully" "{\"enabled\":$ENABLED,\"host\":\"$HOST\",\"interval\":$INTERVAL,\"running\":$running}"
if is_ping_daemon_running; then running=true; fi
send_success "Ping setting updated successfully" "{\"enabled\":$enabled,\"host\":\"$host\",\"interval\":$interval,\"running\":$running}"
else
send_error "NO_DATA" "No data provided"
fi
@@ -301,13 +341,15 @@ handle_post() {
# Handle DELETE request - Reset to default (delete configuration)
handle_delete() {
log_message "DELETE request received"
stop_daemon
if delete_ping_setting; then
# Default is enabled
send_success "Ping setting reset to default" "{\"enabled\":true,\"isDefault\":true,\"running\":false}"
else
send_error "NOT_FOUND" "Ping setting configuration not found"
fi
# Remove ping daemon from services and restart
remove_ping_daemon_from_services
restart_services
# Remove config files
delete_ping_setting
send_success "Ping setting reset to default (disabled)" "{\"enabled\":false,\"running\":false,\"isDefault\":true}"
}
# Main execution

View File

@@ -2,6 +2,49 @@
# AT Queue Manager for OpenWRT with Preemption Support and Token System
# Located in /www/cgi-bin/services/at_queue_manager
# Load centralized logging
. /www/cgi-bin/services/quecmanager_logger.sh
# Script identification for logging
SCRIPT_NAME_LOG="at_queue_manager"
# Test if centralized logging is available and log a test message
if command -v qm_log_info >/dev/null 2>&1; then
qm_log_info "service" "$SCRIPT_NAME_LOG" "Centralized logging system loaded successfully"
else
logger -t at_queue_manager -p daemon.error "Centralized logging functions not found after sourcing"
fi
# Centralized logging function
log_at_queue_manager() {
local level="$1"
local message="$2"
# Fallback logging if centralized system fails
if ! command -v qm_log_error >/dev/null 2>&1; then
logger -t at_queue_manager -p daemon.error "Centralized logging not available, falling back to syslog: $level - $message"
return 1
fi
case "$level" in
"error")
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
;;
"warn")
qm_log_warn "service" "$SCRIPT_NAME_LOG" "$message"
;;
"info")
qm_log_info "service" "$SCRIPT_NAME_LOG" "$message"
;;
"debug")
qm_log_debug "service" "$SCRIPT_NAME_LOG" "$message"
;;
*)
qm_log_error "service" "$SCRIPT_NAME_LOG" "Invalid log level: $level - $message"
;;
esac
}
# Constants
QUEUE_DIR="/tmp/at_queue"
QUEUE_FILE="$QUEUE_DIR/queue"
@@ -39,7 +82,7 @@ acquire_lock() {
while [ $attempt -lt $timeout ]; do
if mkdir "$LOCK_DIR" 2>/dev/null; then
logger -t at_queue -p daemon.debug "Lock acquired"
log_at_queue_manager "debug" "Lock acquired"
return 0
fi
@@ -47,18 +90,18 @@ acquire_lock() {
attempt=$((attempt + 1))
done
logger -t at_queue -p daemon.error "Failed to acquire lock after $timeout attempts"
log_at_queue_manager "error" "Failed to acquire lock after $timeout attempts"
return 1
}
release_lock() {
if [ -d "$LOCK_DIR" ]; then
rmdir "$LOCK_DIR" 2>/dev/null
logger -t at_queue -p daemon.debug "Lock released"
log_at_queue_manager "debug" "Lock released"
return 0
fi
logger -t at_queue -p daemon.error "Lock directory doesn't exist"
log_at_queue_manager "error" "Lock directory doesn't exist"
return 1
}
@@ -69,7 +112,7 @@ init_queue_system() {
chmod 755 "$QUEUE_DIR"
chmod 644 "$QUEUE_FILE"
chmod 755 "$RESULTS_DIR"
logger -t at_queue -p daemon.info "Queue system initialized"
log_at_queue_manager "info" "Queue system initialized"
}
# Cleanup old results and tracking files
@@ -80,7 +123,7 @@ cleanup_old_results() {
find "$QUEUE_DIR" -name "pid.*" -type f -mmin +60 -delete 2>/dev/null
find "$QUEUE_DIR" -name "*.exit" -type f -mmin +60 -delete 2>/dev/null
find "$QUEUE_DIR" -name "start_time.*" -type f -mmin +60 -delete 2>/dev/null
logger -t at_queue -p daemon.debug "Cleaned up old tracking files"
log_at_queue_manager "debug" "Cleaned up old tracking files"
# Use find with -delete and basic timestamp check for OpenWRT
find "$RESULTS_DIR" -name "*.json" -type f -mmin +60 -delete 2>/dev/null || {
@@ -99,12 +142,12 @@ cleanup_old_results() {
local token_time=$(cat "$TOKEN_FILE" | jsonfilter -e '@.timestamp')
if [ $((current_time - token_time)) -gt $TOKEN_TIMEOUT ]; then
local token_holder=$(cat "$TOKEN_FILE" | jsonfilter -e '@.id')
logger -t at_queue -p daemon.warn "Removing expired token from $token_holder"
log_at_queue_manager "warn" "Removing expired token from $token_holder"
rm -f "$TOKEN_FILE"
fi
fi
logger -t at_queue -p daemon.info "Cleanup: Removed files older than 1 hour"
log_at_queue_manager "info" "Cleanup: Removed files older than 1 hour"
}
# Generate unique command ID
@@ -122,7 +165,7 @@ start_execution_tracking() {
echo "$pid" > "$QUEUE_DIR/pid.$cmd_id"
chmod 644 "$QUEUE_DIR/start_time.$cmd_id"
chmod 644 "$QUEUE_DIR/pid.$cmd_id"
logger -t at_queue -p daemon.debug "Started tracking command $cmd_id (PID: $pid)"
log_at_queue_manager "debug" "Started tracking command $cmd_id (PID: $pid)"
}
# Check if running command should be preempted
@@ -131,7 +174,7 @@ should_preempt() {
local new_priority="$2"
if [ ! -f "$QUEUE_DIR/start_time.$current_cmd_id" ]; then
logger -t at_queue -p daemon.debug "No start time found for $current_cmd_id"
log_at_queue_manager "debug" "No start time found for $current_cmd_id"
return 1
fi
@@ -144,16 +187,16 @@ should_preempt() {
if [ -f "$ACTIVE_FILE" ]; then
current_priority=$(cat "$ACTIVE_FILE" | jsonfilter -e '@.priority')
else
logger -t at_queue -p daemon.debug "No active command found"
log_at_queue_manager "debug" "No active command found"
return 1
fi
if [ $execution_time -gt $PREEMPTION_THRESHOLD ] && [ $new_priority -lt $current_priority ]; then
logger -t at_queue -p daemon.info "Command $current_cmd_id (priority $current_priority) running for ${execution_time}s is eligible for preemption by priority $new_priority"
log_at_queue_manager "info" "Command $current_cmd_id (priority $current_priority) running for ${execution_time}s is eligible for preemption by priority $new_priority"
return 0
fi
logger -t at_queue -p daemon.debug "Command $current_cmd_id not eligible for preemption (time: ${execution_time}s, current priority: $current_priority, new priority: $new_priority)"
log_at_queue_manager "debug" "Command $current_cmd_id not eligible for preemption (time: ${execution_time}s, current priority: $current_priority, new priority: $new_priority)"
return 1
}
@@ -164,7 +207,7 @@ preempt_command() {
if [ -f "$pid_file" ]; then
local pid=$(cat "$pid_file")
logger -t at_queue -p daemon.info "Preempting command $cmd_id (PID: $pid)"
log_at_queue_manager "info" "Preempting command $cmd_id (PID: $pid)"
# Send SIGTERM first
kill -TERM $pid 2>/dev/null
@@ -175,7 +218,7 @@ preempt_command() {
# Force kill if still running
if kill -0 $pid 2>/dev/null; then
kill -KILL $pid 2>/dev/null
logger -t at_queue -p daemon.warn "Forced termination of command $cmd_id"
log_at_queue_manager "warn" "Forced termination of command $cmd_id"
fi
# Record preemption result
@@ -185,11 +228,11 @@ preempt_command() {
rm -f "$pid_file" "$QUEUE_DIR/start_time.$cmd_id" "$QUEUE_DIR/$cmd_id.exit"
[ -f "$ACTIVE_FILE" ] && rm -f "$ACTIVE_FILE"
logger -t at_queue -p daemon.info "Command $cmd_id preemption complete"
log_at_queue_manager "info" "Command $cmd_id preemption complete"
return 0
fi
logger -t at_queue -p daemon.warn "No PID file found for command $cmd_id"
log_at_queue_manager "warn" "No PID file found for command $cmd_id"
return 1
}
@@ -227,7 +270,7 @@ EOF
printf "%s" "$response" > "$RESULTS_DIR/$cmd_id.json"
chmod 644 "$RESULTS_DIR/$cmd_id.json"
logger -t at_queue -p daemon.info "Recorded preemption result for command $cmd_id (duration: ${duration}ms)"
log_at_queue_manager "info" "Recorded preemption result for command $cmd_id (duration: ${duration}ms)"
}
# Request a token for direct sms_tool execution
@@ -238,7 +281,7 @@ request_token() {
# Acquire lock first
if ! acquire_lock; then
logger -t at_queue -p daemon.error "Failed to acquire lock for token request"
log_at_queue_manager "error" "Failed to acquire lock for token request"
echo "{\"error\":\"Could not acquire lock\",\"status\":\"denied\"}"
return 1
fi
@@ -252,11 +295,11 @@ request_token() {
# Check for expired token (> TOKEN_TIMEOUT seconds old)
if [ $((current_time - timestamp)) -gt $TOKEN_TIMEOUT ]; then
logger -t at_queue -p daemon.warn "Found expired token from $current_holder, releasing"
log_at_queue_manager "warn" "Found expired token from $current_holder, releasing"
rm -f "$TOKEN_FILE"
# Check for priority preemption
elif [ $priority -lt $current_priority ]; then
logger -t at_queue -p daemon.info "Preempting token from $current_holder (priority: $current_priority) for $requestor_id (priority: $priority)"
log_at_queue_manager "info" "Preempting token from $current_holder (priority: $current_priority) for $requestor_id (priority: $priority)"
rm -f "$TOKEN_FILE"
else
# Token in use and cannot be preempted
@@ -278,7 +321,7 @@ request_token() {
return 1
fi
logger -t at_queue -p daemon.info "Direct execution with higher priority than active queue command"
log_at_queue_manager "info" "Direct execution with higher priority than active queue command"
fi
# Grant token
@@ -296,7 +339,7 @@ release_token() {
local requestor_id="$1"
if ! acquire_lock; then
logger -t at_queue -p daemon.error "Failed to acquire lock for token release"
log_at_queue_manager "error" "Failed to acquire lock for token release"
return 1
fi
@@ -305,15 +348,15 @@ release_token() {
if [ "$current_holder" = "$requestor_id" ]; then
rm -f "$TOKEN_FILE"
logger -t at_queue -p daemon.debug "Token released by $requestor_id"
log_at_queue_manager "debug" "Token released by $requestor_id"
release_lock
echo "{\"status\":\"released\"}"
return 0
else
logger -t at_queue -p daemon.warn "Token release attempted by $requestor_id but held by $current_holder"
log_at_queue_manager "warn" "Token release attempted by $requestor_id but held by $current_holder"
fi
else
logger -t at_queue -p daemon.warn "Token release attempted but no token exists"
log_at_queue_manager "warn" "Token release attempted but no token exists"
fi
release_lock
@@ -331,11 +374,11 @@ enqueue_command() {
# Ensure queue directory exists
[ ! -d "$QUEUE_DIR" ] && init_queue_system
logger -t at_queue -p daemon.info "Enqueuing command: $cmd (priority: $priority, id: $cmd_id)"
log_at_queue_manager "info" "Enqueuing command: $cmd (priority: $priority, id: $cmd_id)"
# Acquire lock for queue modification
if ! acquire_lock; then
logger -t at_queue -p daemon.error "Failed to acquire lock for enqueuing command"
log_at_queue_manager "error" "Failed to acquire lock for enqueuing command"
echo "{\"error\":\"Queue lock acquisition failed\",\"command\":\"$cmd\"}"
return 1
fi
@@ -358,11 +401,11 @@ enqueue_command() {
cat "$QUEUE_FILE" >> "$temp_file"
mv "$temp_file" "$QUEUE_FILE"
chmod 644 "$QUEUE_FILE"
logger -t at_queue -p daemon.info "Added high priority command to front of queue"
log_at_queue_manager "info" "Added high priority command to front of queue"
else
# Normal priority - append to queue
echo "$entry" >> "$QUEUE_FILE"
logger -t at_queue -p daemon.info "Added normal priority command to end of queue"
log_at_queue_manager "info" "Added normal priority command to end of queue"
fi
# Release lock
@@ -379,7 +422,7 @@ dequeue_command() {
# Acquire lock
if ! acquire_lock; then
logger -t at_queue -p daemon.error "Failed to acquire lock for dequeuing command"
log_at_queue_manager "error" "Failed to acquire lock for dequeuing command"
return 1
fi
@@ -395,7 +438,7 @@ dequeue_command() {
# Release lock
release_lock
logger -t at_queue -p daemon.debug "Dequeued command: $(echo "$cmd_entry" | jsonfilter -e '@.command')"
log_at_queue_manager "debug" "Dequeued command: $(echo "$cmd_entry" | jsonfilter -e '@.command')"
echo "$cmd_entry"
}
@@ -433,7 +476,7 @@ execute_with_timeout() {
# Start execution tracking
start_execution_tracking "$cmd_id" "$pid"
logger -t at_queue -p daemon.debug "Started command execution: $command (PID: $pid)"
log_at_queue_manager "debug" "Started command execution: $command (PID: $pid)"
# Wait for completion with shorter polling interval
local start_time=$(date +%s)
@@ -447,7 +490,7 @@ execute_with_timeout() {
# Cleanup
rm -f "$QUEUE_DIR/pid.$cmd_id" "$QUEUE_DIR/$cmd_id.exit" "$output_file" "$QUEUE_DIR/start_time.$cmd_id"
logger -t at_queue -p daemon.debug "Command completed with exit code $exit_code"
log_at_queue_manager "debug" "Command completed with exit code $exit_code"
echo "$output"
return $exit_code
fi
@@ -471,7 +514,7 @@ execute_with_timeout() {
# Cleanup
rm -f "$QUEUE_DIR/pid.$cmd_id" "$QUEUE_DIR/$cmd_id.exit" "$output_file" "$QUEUE_DIR/start_time.$cmd_id"
logger -t at_queue -p daemon.warn "Command timed out after $timeout seconds"
log_at_queue_manager "warn" "Command timed out after $timeout seconds"
echo "${partial_output:-Command timed out after $timeout seconds}"
fi
@@ -487,7 +530,7 @@ execute_command() {
local start_time=$(date +%s%3N)
logger -t at_queue -p daemon.info "Executing command $cmd_id: $cmd_text (priority: $priority)"
log_at_queue_manager "info" "Executing command $cmd_id: $cmd_text (priority: $priority)"
# Execute command with timeout
local result=$(execute_with_timeout "$cmd_text" $MAX_TIMEOUT "$cmd_id")
@@ -501,16 +544,16 @@ execute_command() {
if [ $exit_code -eq 124 ]; then
status="timeout"
logger -t at_queue -p daemon.error "Command $cmd_id timed out after ${duration}ms"
log_at_queue_manager "error" "Command $cmd_id timed out after ${duration}ms"
elif echo "$result" | grep -q "OK"; then
status="success"
log_level="info"
logger -t at_queue -p daemon.info "Command $cmd_id completed successfully in ${duration}ms"
log_at_queue_manager "info" "Command $cmd_id completed successfully in ${duration}ms"
elif echo "$result" | grep -q "CME ERROR"; then
status="cme_error"
logger -t at_queue -p daemon.error "Command $cmd_id failed with CME ERROR in ${duration}ms"
log_at_queue_manager "error" "Command $cmd_id failed with CME ERROR in ${duration}ms"
else
logger -t at_queue -p daemon.error "Command $cmd_id failed with general error in ${duration}ms"
log_at_queue_manager "error" "Command $cmd_id failed with general error in ${duration}ms"
fi
# Clean and escape the output
@@ -536,7 +579,7 @@ EOF
# Acquire lock for writing result
if ! acquire_lock; then
logger -t at_queue -p daemon.error "Failed to acquire lock for writing result"
log_at_queue_manager "error" "Failed to acquire lock for writing result"
else
# Save response
printf "%s" "$response" > "$RESULTS_DIR/$cmd_id.json"
@@ -561,7 +604,7 @@ process_queue() {
# Make sure the lock directory doesn't exist at startup
[ -d "$LOCK_DIR" ] && rmdir "$LOCK_DIR" 2>/dev/null
logger -t at_queue -p daemon.info "Started queue processing daemon"
log_at_queue_manager "info" "Started queue processing daemon"
while true; do
# Quick cleanup check
@@ -579,12 +622,12 @@ process_queue() {
# Check for expired token
if [ $((current_time - token_time)) -gt $TOKEN_TIMEOUT ]; then
logger -t at_queue -p daemon.warn "Removing expired token from $token_holder"
log_at_queue_manager "warn" "Removing expired token from $token_holder"
rm -f "$TOKEN_FILE"
else
# Log pause status only every 5 seconds to reduce log spam
if [ $((current_time - last_log)) -ge 5 ]; then
logger -t at_queue -p daemon.debug "Queue processing paused, token held by $token_holder"
log_at_queue_manager "debug" "Queue processing paused, token held by $token_holder"
last_log=$current_time
fi
sleep $POLL_INTERVAL
@@ -618,42 +661,42 @@ if [ "${SCRIPT_NAME}" != "" ]; then
case "$action" in
"enqueue")
if [ -n "$command" ]; then
logger -t at_queue -p daemon.info "CGI: Received enqueue request for command: $command"
log_at_queue_manager "info" "CGI: Received enqueue request for command: $command"
enqueue_command "$command" "$priority"
else
logger -t at_queue -p daemon.error "CGI: Empty command received"
log_at_queue_manager "error" "CGI: Empty command received"
echo "{\"error\":\"No command specified\"}"
fi
;;
"status")
if [ -f "$ACTIVE_FILE" ]; then
logger -t at_queue -p daemon.debug "CGI: Status request - queue active"
log_at_queue_manager "debug" "CGI: Status request - queue active"
cat "$ACTIVE_FILE"
else
logger -t at_queue -p daemon.debug "CGI: Status request - queue idle"
log_at_queue_manager "debug" "CGI: Status request - queue idle"
echo "{\"status\":\"idle\"}"
fi
;;
"request_token")
if [ -n "$id" ]; then
logger -t at_queue -p daemon.info "Token request from $id (priority: ${priority:-10})"
log_at_queue_manager "info" "Token request from $id (priority: ${priority:-10})"
request_token "$id" "${priority:-10}" "${timeout:-10}"
else
logger -t at_queue -p daemon.error "Token request missing ID"
log_at_queue_manager "error" "Token request missing ID"
echo "{\"error\":\"No requestor ID specified\",\"status\":\"denied\"}"
fi
;;
"release_token")
if [ -n "$id" ]; then
logger -t at_queue -p daemon.info "Token release from $id"
log_at_queue_manager "info" "Token release from $id"
release_token "$id"
else
logger -t at_queue -p daemon.error "Token release missing ID"
log_at_queue_manager "error" "Token release missing ID"
echo "{\"error\":\"No requestor ID specified\",\"status\":\"denied\"}"
fi
;;
*)
logger -t at_queue -p daemon.error "CGI: Invalid action received: $action"
log_at_queue_manager "error" "CGI: Invalid action received: $action"
echo "{\"error\":\"Invalid action\"}"
;;
esac
@@ -668,5 +711,7 @@ fi
# If not run as CGI, start queue processing
if [ "${SCRIPT_NAME}" = "" ] && [ -z "$1" ]; then
# Test logging immediately on startup
log_at_queue_manager "info" "AT Queue Manager starting up - PID: $$"
process_queue
fi
fi

View File

@@ -2,9 +2,6 @@
# Updated QuecProfiles daemon with enhanced SA/NSA NR5G band management and TTL support
# Including profile application functions and fixed comparison logic
# Load centralized logging
. /www/cgi-bin/services/quecmanager_logger.sh
# Configuration
QUEUE_DIR="/tmp/at_queue"
TOKEN_FILE="$QUEUE_DIR/token"
@@ -18,49 +15,25 @@ DEFAULT_CHECK_INTERVAL=60 # Default check interval in seconds
COMMAND_TIMEOUT=10 # Default timeout for AT commands in seconds
QUEUE_PRIORITY=3 # Medium-high priority (1 is highest for cell scan)
MAX_TOKEN_WAIT=15 # Maximum seconds to wait for token acquisition
SCRIPT_NAME_LOG="quecprofiles_daemon"
# Initialize log files and use centralized logging
mkdir -p "$(dirname "$DEBUG_LOG")" "$(dirname "$DETAILED_LOG")"
touch "$DEBUG_LOG" "$DETAILED_LOG"
chmod 644 "$DEBUG_LOG" "$DETAILED_LOG"
# Log startup message using centralized logging
qm_log_info "service" "$SCRIPT_NAME_LOG" "Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)"
# Also maintain file logging for compatibility
# Initialize log file
echo "$(date) - Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)" >"$DEBUG_LOG"
echo "$(date) - Starting QuecProfiles daemon with SA/NSA NR5G and TTL support (PID: $$)" >"$DETAILED_LOG"
chmod 644 "$DEBUG_LOG" "$DETAILED_LOG"
# Function to log messages - now uses centralized logging
# Function to log messages
log_message() {
local message="$1"
local level="${2:-info}"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
# Use centralized logging
case "$level" in
"error")
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
;;
"warn")
qm_log_warn "service" "$SCRIPT_NAME_LOG" "$message"
;;
"debug")
qm_log_debug "service" "$SCRIPT_NAME_LOG" "$message"
;;
*)
qm_log_info "service" "$SCRIPT_NAME_LOG" "$message"
;;
esac
# Also maintain system logging for compatibility
# Log to system log
logger -t quecprofiles_daemon -p "daemon.$level" "$message"
# Log to debug file (maintain existing behavior)
# Log to debug file
echo "[$timestamp] [$level] $message" >>"$DEBUG_LOG"
# For detailed logs or errors (maintain existing behavior)
# For detailed logs or errors
if [ "$level" = "error" ] || [ "$level" = "debug" ]; then
echo "[$timestamp] [$level] $message" >>"$DETAILED_LOG"
fi

View File

@@ -3,9 +3,6 @@
# QuecWatch Daemon
# Monitors cellular connectivity and performs recovery actions
# Load centralized logging
. /www/cgi-bin/services/quecmanager_logger.sh
# Load UCI configuration functions
. /lib/functions.sh
@@ -20,7 +17,6 @@ RETRY_COUNT_FILE="/tmp/quecwatch_retry_count"
UCI_CONFIG="quecmanager"
MAX_TOKEN_WAIT=10 # Maximum seconds to wait for token acquisition
TOKEN_PRIORITY=15 # Medium priority (between profiles and metrics)
SCRIPT_NAME_LOG="quecwatch"
# Ensure directories exist
mkdir -p "$LOG_DIR" "$QUEUE_DIR"
@@ -29,33 +25,17 @@ mkdir -p "$LOG_DIR" "$QUEUE_DIR"
echo "$$" > "$PID_FILE"
chmod 644 "$PID_FILE"
# Function to log messages - now uses centralized logging
# Function to log messages
log_message() {
local level="${2:-info}"
local message="$1"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
# Use centralized logging
case "$level" in
"error")
qm_log_error "service" "$SCRIPT_NAME_LOG" "$message"
;;
"warn")
qm_log_warn "service" "$SCRIPT_NAME_LOG" "$message"
;;
"debug")
qm_log_debug "service" "$SCRIPT_NAME_LOG" "$message"
;;
*)
qm_log_info "service" "$SCRIPT_NAME_LOG" "$message"
;;
esac
# Also maintain system logging for compatibility
logger -t quecwatch -p "daemon.$level" "$message"
# Log to file (maintain existing behavior)
# Log to file
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
# Log to system log
logger -t quecwatch -p "daemon.$level" "$message"
}
# Function to update status