Copy QuecManager beta to non-beta

QM BETA --> regular/non-beta
This commit is contained in:
Cameron Thompson
2025-08-31 02:17:49 -04:00
parent 6d6a3775c4
commit 02dafc73ad
391 changed files with 4494 additions and 740 deletions

View File

@@ -0,0 +1,110 @@
#!/bin/sh
# QuecManager Log Cleanup Script
# Periodically clean up old log files to prevent /tmp from filling up
. /www/cgi-bin/services/quecmanager_logger.sh
# Configuration
MAX_LOG_AGE_DAYS=7 # Delete logs older than 7 days
MAX_BACKUP_FILES=2 # Keep maximum 2 backup files (.1, .2)
CLEANUP_LOG_SIZE=1000 # Run cleanup if any log exceeds 1MB
# Function to log cleanup activities
log_cleanup() {
qm_log_info "system" "log_cleanup" "$1"
}
# Initialize
qm_init_logs
log_cleanup "Starting log cleanup process"
# Cleanup function
perform_cleanup() {
local files_cleaned=0
local space_freed=0
# Clean up old backup files
if [ -d "$QM_LOG_BASE" ]; then
# Remove backup files older than specified days
old_backups=$(find "$QM_LOG_BASE" -name "*.1" -o -name "*.2" -type f -mtime +$MAX_LOG_AGE_DAYS 2>/dev/null)
for backup_file in $old_backups; do
if [ -f "$backup_file" ]; then
file_size=$(du -k "$backup_file" 2>/dev/null | cut -f1)
rm -f "$backup_file" 2>/dev/null
if [ $? -eq 0 ]; then
files_cleaned=$((files_cleaned + 1))
space_freed=$((space_freed + ${file_size:-0}))
log_cleanup "Removed old backup file: $(basename "$backup_file")"
fi
fi
done
# Force rotation for large log files
for category_dir in "$QM_LOG_DAEMONS" "$QM_LOG_SERVICES" "$QM_LOG_SETTINGS" "$QM_LOG_SYSTEM"; do
if [ -d "$category_dir" ]; then
for logfile in "$category_dir"/*.log; do
if [ -f "$logfile" ]; then
# Check file size in KB
file_size_kb=$(du -k "$logfile" 2>/dev/null | cut -f1)
if [ "${file_size_kb:-0}" -gt $CLEANUP_LOG_SIZE ]; then
log_cleanup "Rotating large log file: $(basename "$logfile") (${file_size_kb}KB)"
qm_rotate_log "$logfile"
files_cleaned=$((files_cleaned + 1))
fi
fi
done
fi
done
# Additional cleanup: remove empty log files
empty_logs=$(find "$QM_LOG_BASE" -name "*.log" -type f -size 0 2>/dev/null)
for empty_log in $empty_logs; do
rm -f "$empty_log" 2>/dev/null
if [ $? -eq 0 ]; then
files_cleaned=$((files_cleaned + 1))
log_cleanup "Removed empty log file: $(basename "$empty_log")"
fi
done
fi
# Log cleanup summary
if [ $files_cleaned -gt 0 ]; then
log_cleanup "Cleanup completed: $files_cleaned files processed, ${space_freed}KB freed"
else
log_cleanup "Cleanup completed: no files needed cleaning"
fi
}
# Check if we should run cleanup based on disk usage
check_disk_usage() {
# Check /tmp usage (OpenWrt compatible)
local tmp_usage=""
# Try df first (most common)
if command -v df >/dev/null 2>&1; then
tmp_usage=$(df /tmp 2>/dev/null | awk 'NR==2 {print $5}' | tr -d '%')
fi
# If we got a valid percentage and it's high, force cleanup
if [ -n "$tmp_usage" ] && [ "$tmp_usage" -gt 80 ]; then
log_cleanup "High /tmp usage detected (${tmp_usage}%), forcing cleanup"
return 0
fi
# Always run periodic cleanup
return 0
}
# Main execution
if check_disk_usage; then
perform_cleanup
else
log_cleanup "Disk usage check passed, skipping cleanup"
fi
# Clean up centralized log helper's old logs too
qm_cleanup_logs
log_cleanup "Log cleanup process completed"

View File

@@ -0,0 +1,227 @@
#!/bin/sh
# Simple QCAINFO Interpreter
# Configuration
QCAINFO_FILE="/www/signal_graphs/qcainfo.json"
INTERPRETED_FILE="/tmp/interpreted_result.json"
DEBUG_LOG="/tmp/qcainfo_interpreter.log"
INTERVAL=15
# Simple logging function
log() {
echo "$(date): $1" >> "$DEBUG_LOG"
}
# Parse QCAINFO output to extract band and EARFCN
parse_entry() {
local output="$1"
local datetime="$2"
# Extract band and EARFCN using simple grep
local band=$(echo "$output" | grep -o 'LTE BAND [0-9]*' | head -1)
local earfcn=$(echo "$output" | grep -o '+QCAINFO: "PCC",[0-9]*' | grep -o '[0-9]*' | head -1)
local pci=$(echo "$output" | grep -o '+QCAINFO: "PCC",[0-9]*,[0-9]*' | grep -o ',[0-9]*,' | tr -d ',' | head -1)
# Check for SCC (carrier aggregation)
local has_scc=""
if echo "$output" | grep -q '+QCAINFO: "SCC"'; then
has_scc="yes"
else
has_scc="no"
fi
echo "${datetime}|${band}|${earfcn}|${pci}|${has_scc}"
}
# Compare two entries and generate interpretation
generate_interpretation() {
local old_entry="$1"
local new_entry="$2"
# Parse entries
local old_datetime=$(echo "$old_entry" | cut -d'|' -f1)
local old_band=$(echo "$old_entry" | cut -d'|' -f2)
local old_earfcn=$(echo "$old_entry" | cut -d'|' -f3)
local old_pci=$(echo "$old_entry" | cut -d'|' -f4)
local old_scc=$(echo "$old_entry" | cut -d'|' -f5)
local new_datetime=$(echo "$new_entry" | cut -d'|' -f1)
local new_band=$(echo "$new_entry" | cut -d'|' -f2)
local new_earfcn=$(echo "$new_entry" | cut -d'|' -f3)
local new_pci=$(echo "$new_entry" | cut -d'|' -f4)
local new_scc=$(echo "$new_entry" | cut -d'|' -f5)
local time_only=$(echo "$new_datetime" | awk '{print $2}' | cut -d: -f1,2)
local interpretation=""
# Check for band change
if [ "$old_band" != "$new_band" ]; then
interpretation="${interpretation}At ${time_only}, your modem changed primary band from ${old_band} to ${new_band}. "
fi
# Check for EARFCN change
if [ "$old_earfcn" != "$new_earfcn" ]; then
interpretation="${interpretation}At ${time_only}, your modem changed primary EARFCN from ${old_earfcn} to ${new_earfcn}. "
fi
# Check for PCI change
if [ "$old_pci" != "$new_pci" ]; then
interpretation="${interpretation}At ${time_only}, your modem changed primary PCI from ${old_pci} to ${new_pci}. "
fi
# Check for carrier aggregation changes
if [ "$old_scc" = "no" ] && [ "$new_scc" = "yes" ]; then
interpretation="${interpretation}At ${time_only}, your modem activated carrier aggregation. "
elif [ "$old_scc" = "yes" ] && [ "$new_scc" = "no" ]; then
interpretation="${interpretation}At ${time_only}, your modem deactivated carrier aggregation. "
fi
echo "$interpretation"
}
# Add interpretation to JSON file without jq
add_interpretation() {
local interpretation="$1"
local datetime="$2"
if [ -z "$interpretation" ]; then
return
fi
# Initialize file if it doesn't exist
if [ ! -f "$INTERPRETED_FILE" ]; then
echo "[]" > "$INTERPRETED_FILE"
fi
# Read existing content
local existing_content=$(cat "$INTERPRETED_FILE")
# Escape quotes in interpretation
local escaped_interpretation=$(echo "$interpretation" | sed 's/"/\\"/g')
# Create new entry
local new_entry="{\"datetime\":\"$datetime\",\"interpretation\":\"$escaped_interpretation\"}"
# Add to array
if [ "$existing_content" = "[]" ]; then
echo "[$new_entry]" > "$INTERPRETED_FILE"
else
# Remove closing bracket, add comma and new entry
echo "$existing_content" | sed 's/]$//' > "$INTERPRETED_FILE.tmp"
echo ",$new_entry]" >> "$INTERPRETED_FILE.tmp"
mv "$INTERPRETED_FILE.tmp" "$INTERPRETED_FILE"
fi
log "Added interpretation: $interpretation"
}
# Main processing function
process_qcainfo() {
if [ ! -f "$QCAINFO_FILE" ]; then
log "QCAINFO file not found: $QCAINFO_FILE"
return
fi
# Get total entries
local total_entries=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
if [ -z "$total_entries" ] || [ "$total_entries" = "null" ] || [ "$total_entries" -lt 2 ]; then
log "Not enough entries to compare (need at least 2, found: $total_entries)"
return
fi
log "Found $total_entries entries in QCAINFO file"
# Get last two entries
local last_entry=$(jq -r '.[-1]' "$QCAINFO_FILE" 2>/dev/null)
local second_last_entry=$(jq -r '.[-2]' "$QCAINFO_FILE" 2>/dev/null)
if [ "$last_entry" = "null" ] || [ "$second_last_entry" = "null" ]; then
log "Failed to get last two entries"
return
fi
# Extract data from JSON entries
local last_datetime=$(echo "$last_entry" | jq -r '.datetime')
local last_output=$(echo "$last_entry" | jq -r '.output')
local second_datetime=$(echo "$second_last_entry" | jq -r '.datetime')
local second_output=$(echo "$second_last_entry" | jq -r '.output')
log "Comparing entries: $second_datetime vs $last_datetime"
# Parse entries
local parsed_second=$(parse_entry "$second_output" "$second_datetime")
local parsed_last=$(parse_entry "$last_output" "$last_datetime")
log "Parsed second: $parsed_second"
log "Parsed last: $parsed_last"
# Generate interpretation
local interpretation=$(generate_interpretation "$parsed_second" "$parsed_last")
if [ -n "$interpretation" ]; then
add_interpretation "$interpretation" "$last_datetime"
log "Generated interpretation for $last_datetime"
else
log "No changes detected between $second_datetime and $last_datetime"
fi
}
# Initialize
log "QCAINFO Interpreter started (PID: $$)"
# Initialize interpreted results file
if [ ! -f "$INTERPRETED_FILE" ]; then
echo "[]" > "$INTERPRETED_FILE"
log "Initialized interpreted results file"
fi
# Process all existing data once at startup
log "Processing all existing QCAINFO data..."
if [ -f "$QCAINFO_FILE" ]; then
total=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
if [ "$total" -gt 1 ]; then
# Process all consecutive pairs
i=1
while [ $i -lt $total ]; do
prev_entry=$(jq -r ".[$((i-1))]" "$QCAINFO_FILE" 2>/dev/null)
curr_entry=$(jq -r ".[$i]" "$QCAINFO_FILE" 2>/dev/null)
if [ "$prev_entry" != "null" ] && [ "$curr_entry" != "null" ]; then
prev_datetime=$(echo "$prev_entry" | jq -r '.datetime')
prev_output=$(echo "$prev_entry" | jq -r '.output')
curr_datetime=$(echo "$curr_entry" | jq -r '.datetime')
curr_output=$(echo "$curr_entry" | jq -r '.output')
parsed_prev=$(parse_entry "$prev_output" "$prev_datetime")
parsed_curr=$(parse_entry "$curr_output" "$curr_datetime")
interpretation=$(generate_interpretation "$parsed_prev" "$parsed_curr")
if [ -n "$interpretation" ]; then
add_interpretation "$interpretation" "$curr_datetime"
fi
fi
i=$((i + 1))
done
log "Completed processing all existing data ($total entries)"
else
log "Not enough existing data to process"
fi
fi
# Remember last processed entry count
last_count=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
# Main monitoring loop
log "Starting continuous monitoring (checking every $INTERVAL seconds)"
while true; do
sleep "$INTERVAL"
current_count=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null)
if [ "$current_count" -gt "$last_count" ]; then
log "New entries detected: $last_count -> $current_count"
process_qcainfo
last_count="$current_count"
fi
done

View File

@@ -164,7 +164,23 @@ process_all_metrics() {
"$logfile" > "$temp_file" 2>/dev/null && mv "$temp_file" "$logfile"
chmod 644 "$logfile"
fi
sleep 0.5
# QCAINFO with time stamp
local usage_output=$(execute_at_command "AT+QCAINFO")
if [ -n "$usage_output" ] && echo "$usage_output" | grep -q "QCAINFO"; then
local logfile="$LOGDIR/qcainfo.json"
[ ! -s "$logfile" ] && echo "[]" > "$logfile"
local temp_file="${logfile}.tmp.$$"
jq --arg dt "$timestamp" \
--arg out "$usage_output" \
'. + [{"datetime": $dt, "output": $out}] | .[-'"$MAX_ENTRIES"':]' \
"$logfile" > "$temp_file" 2>/dev/null && mv "$temp_file" "$logfile"
chmod 644 "$logfile"
fi
# Release token
release_token "$metrics_id"
logger -t at_queue -p daemon.info "Metrics processing completed"

View File

@@ -0,0 +1,201 @@
#!/bin/sh
# Memory Daemon - Monitors system memory usage and writes to JSON file
# This daemon only runs when memory monitoring is enabled via settings
set -eu
# Ensure PATH for OpenWrt/BusyBox
export PATH="/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
# Load centralized logging
. /www/cgi-bin/services/quecmanager_logger.sh
# Configuration
TMP_DIR="/tmp/quecmanager"
OUT_JSON="$TMP_DIR/memory.json"
PID_FILE="$TMP_DIR/memory_daemon.pid"
CONFIG_FILE="/etc/quecmanager/settings/memory_settings.conf"
[ -f "$CONFIG_FILE" ] || CONFIG_FILE="/tmp/quecmanager/settings/memory_settings.conf"
DEFAULT_INTERVAL=1
SCRIPT_NAME="memory_daemon"
# Ensure temp directory exists
ensure_tmp_dir() {
[ -d "$TMP_DIR" ] || mkdir -p "$TMP_DIR" || exit 1
}
# Logging function
log() {
qm_log_info "daemon" "$SCRIPT_NAME" "$1"
}
# Check if this daemon instance is already running
daemon_is_running() {
if [ -f "$PID_FILE" ]; then
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
# Verify it's actually our daemon by checking process cmdline
if [ -r "/proc/$pid/cmdline" ] && grep -q "memory_daemon.sh" "/proc/$pid/cmdline" 2>/dev/null; then
return 0
else
# PID file is stale, remove it
rm -f "$PID_FILE" 2>/dev/null || true
fi
fi
fi
return 1
}
# Write our PID to file
write_pid() {
echo "$$" > "$PID_FILE"
}
# Cleanup function
cleanup() {
rm -f "$PID_FILE" 2>/dev/null || true
log "Memory daemon stopped"
}
# Create default config if none exists
create_default_config() {
local primary_config="/etc/quecmanager/settings/memory_settings.conf"
local fallback_config="/tmp/quecmanager/settings/memory_settings.conf"
if [ ! -f "$primary_config" ] && [ ! -f "$fallback_config" ]; then
log "No config file found, creating default configuration"
# Try primary location first
if mkdir -p "/etc/quecmanager/settings" 2>/dev/null; then
{
echo "MEMORY_ENABLED=false"
echo "MEMORY_INTERVAL=1"
} > "$primary_config" 2>/dev/null && {
chmod 644 "$primary_config" 2>/dev/null || true
CONFIG_FILE="$primary_config"
log "Created default config at $primary_config"
return 0
}
fi
# Fallback to tmp location
mkdir -p "/tmp/quecmanager/settings" 2>/dev/null || true
{
echo "MEMORY_ENABLED=false"
echo "MEMORY_INTERVAL=1"
} > "$fallback_config" && {
chmod 644 "$fallback_config" 2>/dev/null || true
CONFIG_FILE="$fallback_config"
log "Created default config at $fallback_config"
return 0
}
log "Failed to create default config file"
return 1
fi
}
# Read configuration from file
read_config() {
ENABLED="false"
INTERVAL="$DEFAULT_INTERVAL"
if [ -f "$CONFIG_FILE" ]; then
MEMORY_ENABLED=$(grep -E "^MEMORY_ENABLED=" "$CONFIG_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2 | tr -d '\r' | tr -d '"')
MEMORY_INTERVAL=$(grep -E "^MEMORY_INTERVAL=" "$CONFIG_FILE" 2>/dev/null | tail -n1 | cut -d'=' -f2 | tr -d '\r')
case "${MEMORY_ENABLED:-}" in
true|1|on|yes|enabled) ENABLED="true" ;;
*) ENABLED="false" ;;
esac
if echo "${MEMORY_INTERVAL:-}" | grep -qE '^[0-9]+$'; then
if [ "$MEMORY_INTERVAL" -ge 1 ] && [ "$MEMORY_INTERVAL" -le 10 ]; then
INTERVAL="$MEMORY_INTERVAL"
fi
fi
fi
}
# Write JSON data atomically
write_json_atomic() {
local json_data="$1"
local tmpfile="$(mktemp "$TMP_DIR/memory.XXXXXX" 2>/dev/null || echo "$TMP_DIR/memory.tmp.$$")"
if [ -n "$tmpfile" ] && printf '%s' "$json_data" > "$tmpfile" 2>/dev/null; then
mv "$tmpfile" "$OUT_JSON" 2>/dev/null || {
# Fallback if move fails
printf '%s' "$json_data" > "$OUT_JSON" 2>/dev/null || true
rm -f "$tmpfile" 2>/dev/null || true
}
else
# Direct write fallback
printf '%s' "$json_data" > "$OUT_JSON" 2>/dev/null || true
rm -f "$tmpfile" 2>/dev/null || true
fi
}
# Main execution starts here
ensure_tmp_dir
log "Starting memory daemon (PID: $$)"
# Check if already running
if daemon_is_running; then
log "Memory daemon already running, exiting"
exit 0
fi
# Create default config if needed
create_default_config
# Set up signal handlers
trap cleanup EXIT INT TERM
write_pid
# Main monitoring loop
while true; do
read_config
# Exit if disabled
if [ "$ENABLED" != "true" ]; then
log "Memory monitoring disabled in config, exiting"
exit 0
fi
# Get current timestamp
ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
# Get memory information using /proc/meminfo (most reliable method)
if [ -r "/proc/meminfo" ]; then
# Extract values from /proc/meminfo (values are in kB)
TOTAL_KB=$(grep "^MemTotal:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
AVAIL_KB=$(grep "^MemAvailable:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
FREE_KB=$(grep "^MemFree:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
# If MemAvailable is not available (older kernels), estimate it
if [ "$AVAIL_KB" = "0" ]; then
CACHED_KB=$(grep "^Cached:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
BUFFERS_KB=$(grep "^Buffers:" /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0")
AVAIL_KB=$((FREE_KB + CACHED_KB + BUFFERS_KB))
fi
# Convert to bytes (multiply by 1024)
TOTAL_BYTES=$((TOTAL_KB * 1024))
AVAIL_BYTES=$((AVAIL_KB * 1024))
USED_BYTES=$((TOTAL_BYTES - AVAIL_BYTES))
json="{\"total\": $TOTAL_BYTES, \"used\": $USED_BYTES, \"available\": $AVAIL_BYTES, \"timestamp\": \"$ts\"}"
else
# Fallback if /proc/meminfo is not available
log "Warning: /proc/meminfo not readable, using error response"
json="{\"total\": 0, \"used\": 0, \"available\": 0, \"timestamp\": \"$ts\", \"error\": \"meminfo_unavailable\"}"
fi
# Write the JSON data
write_json_atomic "$json"
log "Updated memory data: total=${TOTAL_KB:-0}KB, used=${USED_BYTES:-0}B, available=${AVAIL_KB:-0}KB"
# Sleep for the configured interval
sleep "$INTERVAL"
done

View File

@@ -0,0 +1,372 @@
#!/bin/sh
# Network Insights Interpreter Service
# Monitors qcainfo.json and generates network event interpretations
# OpenWrt/BusyBox compatible version
# Configuration
QCAINFO_FILE="/www/signal_graphs/qcainfo.json"
INTERPRETED_FILE="/tmp/interpreted_result.json"
LAST_ENTRY_FILE="/tmp/last_qcainfo_entry.json"
LOCKFILE="/tmp/network_interpreter.lock"
MAX_INTERPRETATIONS=50
# Logging function (OpenWrt compatible)
log_message() {
if command -v logger >/dev/null 2>&1; then
logger -t network_interpreter -p daemon.info "$1"
else
# Use simpler date format for BusyBox
echo "$(date) [network_interpreter] $1" >&2
fi
}
# Convert datetime to timestamp (OpenWrt/BusyBox compatible)
datetime_to_timestamp() {
local datetime="$1"
# Try GNU date first, fallback to string comparison for BusyBox
if date -d "$datetime" +%s >/dev/null 2>&1; then
date -d "$datetime" +%s
else
# For BusyBox, just return the datetime string for string comparison
# This is less precise but works for sequential comparison
echo "$datetime"
fi
}
# Compare timestamps/datetime strings (OpenWrt compatible)
is_datetime_newer() {
local datetime1="$1"
local datetime2="$2"
local ts1=$(datetime_to_timestamp "$datetime1")
local ts2=$(datetime_to_timestamp "$datetime2")
# If we got numeric timestamps, compare numerically
if [ "$ts1" -eq "$ts1" ] 2>/dev/null && [ "$ts2" -eq "$ts2" ] 2>/dev/null; then
[ "$ts1" -gt "$ts2" ]
else
# Fall back to string comparison (works for ISO format)
[ "$datetime1" \> "$datetime2" ]
fi
}
# Parse QCAINFO output to extract band information
parse_qcainfo_bands() {
local output="$1"
# Clean up the output - remove escape sequences and extra characters
local clean_output=$(echo "$output" | tr -d '\r' | sed 's/\\r//g; s/\\n/\n/g')
# Extract all band information from QCAINFO lines
echo "$clean_output" | grep "+QCAINFO:" | while IFS= read -r line; do
if echo "$line" | grep -q "LTE BAND"; then
band=$(echo "$line" | sed -n 's/.*"LTE BAND \([0-9][0-9]*\)".*/B\1/p')
if [ -n "$band" ]; then
echo "LTE:$band"
fi
elif echo "$line" | grep -q "NR5G BAND"; then
band=$(echo "$line" | sed -n 's/.*"NR5G BAND \([0-9][0-9]*\)".*/N\1/p')
if [ -n "$band" ]; then
echo "NR5G:$band"
fi
fi
done
}
# Get network mode from bands
get_network_mode() {
local bands="$1"
local has_lte=false
local has_nr5g=false
if echo "$bands" | grep -q "LTE:"; then
has_lte=true
fi
if echo "$bands" | grep -q "NR5G:"; then
has_nr5g=true
fi
if [ "$has_lte" = true ] && [ "$has_nr5g" = true ]; then
echo "NSA"
elif [ "$has_lte" = true ]; then
echo "LTE"
elif [ "$has_nr5g" = true ]; then
echo "SA"
else
echo "NO_SIGNAL"
fi
}
# Get band list from parsed bands
get_band_list() {
local bands="$1"
if [ -z "$bands" ]; then
echo ""
return
fi
echo "$bands" | sed 's/LTE://g; s/NR5G://g' | sort -u | tr '\n' ',' | sed 's/,$//'
}
# Get carrier count
get_carrier_count() {
local bands="$1"
if [ -z "$bands" ]; then
echo "0"
return
fi
echo "$bands" | wc -l
}
# Compare two band configurations and generate interpretation
compare_configurations() {
local base_output="$1"
local new_output="$2"
local base_datetime="$3"
local new_datetime="$4"
# Parse both configurations
local base_bands=$(parse_qcainfo_bands "$base_output")
local new_bands=$(parse_qcainfo_bands "$new_output")
local base_mode=$(get_network_mode "$base_bands")
local new_mode=$(get_network_mode "$new_bands")
local base_band_list=$(get_band_list "$base_bands")
local new_band_list=$(get_band_list "$new_bands")
local base_carrier_count=$(get_carrier_count "$base_bands")
local new_carrier_count=$(get_carrier_count "$new_bands")
local interpretations=""
# Check for no signal condition
if [ "$new_mode" = "NO_SIGNAL" ]; then
if [ "$base_mode" != "NO_SIGNAL" ]; then
interpretations="Signal lost - No cellular connection detected"
fi
# Check if signal was restored
elif [ "$base_mode" = "NO_SIGNAL" ] && [ "$new_mode" != "NO_SIGNAL" ]; then
interpretations="Signal restored - Connected to $new_mode network"
if [ -n "$new_band_list" ]; then
interpretations="$interpretations ($new_band_list)"
fi
# Check if CA was activated immediately upon signal restoration
if [ "$new_carrier_count" -gt 1 ]; then
interpretations="$interpretations; Carrier Aggregation activated - Now using $new_carrier_count carriers"
fi
else
# Network mode changes
if [ "$base_mode" != "$new_mode" ]; then
case "$new_mode" in
"LTE")
if [ "$base_mode" = "NSA" ]; then
interpretations="Network mode changed from NSA to LTE-only"
elif [ "$base_mode" = "SA" ]; then
interpretations="Network mode changed from 5G SA to LTE"
fi
;;
"SA")
if [ "$base_mode" = "LTE" ]; then
interpretations="Network mode changed from LTE to 5G SA"
elif [ "$base_mode" = "NSA" ]; then
interpretations="Network mode changed from NSA to 5G SA"
fi
;;
"NSA")
if [ "$base_mode" = "LTE" ]; then
interpretations="Network mode changed from LTE to NSA"
elif [ "$base_mode" = "SA" ]; then
interpretations="Network mode changed from 5G SA to NSA"
fi
;;
esac
fi
# Band changes
if [ "$base_band_list" != "$new_band_list" ]; then
if [ -n "$interpretations" ]; then
interpretations="$interpretations; "
fi
# Find added and removed bands
local added_bands=""
local removed_bands=""
# Check for new bands
for band in $(echo "$new_band_list" | tr ',' ' '); do
if [ -n "$band" ] && ! echo "$base_band_list" | grep -q "$band"; then
if [ -n "$added_bands" ]; then
added_bands="$added_bands, $band"
else
added_bands="$band"
fi
fi
done
# Check for removed bands
for band in $(echo "$base_band_list" | tr ',' ' '); do
if [ -n "$band" ] && ! echo "$new_band_list" | grep -q "$band"; then
if [ -n "$removed_bands" ]; then
removed_bands="$removed_bands, $band"
else
removed_bands="$band"
fi
fi
done
if [ -n "$added_bands" ] && [ -n "$removed_bands" ]; then
interpretations="${interpretations}Band configuration changed - Added: $added_bands, Removed: $removed_bands"
elif [ -n "$added_bands" ]; then
interpretations="${interpretations}New bands added: $added_bands"
elif [ -n "$removed_bands" ]; then
interpretations="${interpretations}Bands removed: $removed_bands"
else
interpretations="${interpretations}Band sequence changed from ($base_band_list) to ($new_band_list)"
fi
fi
# Carrier Aggregation changes
if [ "$base_carrier_count" != "$new_carrier_count" ]; then
if [ -n "$interpretations" ]; then
interpretations="$interpretations; "
fi
if [ "$new_carrier_count" -gt 1 ] && [ "$base_carrier_count" -le 1 ]; then
interpretations="${interpretations}Carrier Aggregation activated - Now using $new_carrier_count carriers"
elif [ "$new_carrier_count" -le 1 ] && [ "$base_carrier_count" -gt 1 ]; then
interpretations="${interpretations}Carrier Aggregation deactivated - Single carrier mode"
elif [ "$new_carrier_count" -gt "$base_carrier_count" ]; then
interpretations="${interpretations}Additional carriers aggregated - Carriers increased from $base_carrier_count to $new_carrier_count"
elif [ "$new_carrier_count" -lt "$base_carrier_count" ]; then
interpretations="${interpretations}Carriers reduced from $base_carrier_count to $new_carrier_count"
fi
fi
fi
# Return interpretation if any changes detected
if [ -n "$interpretations" ]; then
echo "$interpretations"
fi
}
# Add interpretation to JSON file
add_interpretation() {
local datetime="$1"
local interpretation="$2"
# Initialize file if it doesn't exist
if [ ! -f "$INTERPRETED_FILE" ]; then
echo "[]" > "$INTERPRETED_FILE"
fi
# Add new interpretation using jq
local temp_file="${INTERPRETED_FILE}.tmp.$$"
jq --arg dt "$datetime" \
--arg interp "$interpretation" \
'. + [{"datetime": $dt, "interpretation": $interp}] | .[-'"$MAX_INTERPRETATIONS"':]' \
"$INTERPRETED_FILE" > "$temp_file" 2>/dev/null && mv "$temp_file" "$INTERPRETED_FILE"
chmod 644 "$INTERPRETED_FILE"
log_message "Added interpretation: $interpretation"
}
# Process QCAINFO entries and generate interpretations
process_qcainfo_data() {
if [ ! -f "$QCAINFO_FILE" ]; then
log_message "QCAINFO file not found: $QCAINFO_FILE"
return 1
fi
# Get total number of entries
local total_entries=$(jq 'length' "$QCAINFO_FILE" 2>/dev/null || echo "0")
if [ "$total_entries" -lt 2 ]; then
log_message "Not enough entries to compare ($total_entries)"
return 0
fi
# Get the last processed entry timestamp
local last_processed=""
if [ -f "$LAST_ENTRY_FILE" ]; then
last_processed=$(cat "$LAST_ENTRY_FILE" 2>/dev/null)
fi
# Process entries sequentially
local i=0
while [ "$i" -lt $((total_entries - 1)) ]; do
local base_entry=$(jq -r ".[$i]" "$QCAINFO_FILE" 2>/dev/null)
local next_entry=$(jq -r ".[$(($i + 1))]" "$QCAINFO_FILE" 2>/dev/null)
local base_datetime=$(echo "$base_entry" | jq -r '.datetime' 2>/dev/null)
local next_datetime=$(echo "$next_entry" | jq -r '.datetime' 2>/dev/null)
local base_output=$(echo "$base_entry" | jq -r '.output' 2>/dev/null)
local next_output=$(echo "$next_entry" | jq -r '.output' 2>/dev/null)
# Skip if this entry was already processed
if [ -n "$last_processed" ] && [ "$next_datetime" = "$last_processed" ]; then
i=$((i + 1))
continue
fi
# Only process entries after the last processed one
if [ -n "$last_processed" ]; then
if ! is_datetime_newer "$next_datetime" "$last_processed"; then
i=$((i + 1))
continue
fi
fi
# Compare configurations and generate interpretation
local interpretation=$(compare_configurations "$base_output" "$next_output" "$base_datetime" "$next_datetime")
if [ -n "$interpretation" ]; then
add_interpretation "$next_datetime" "$interpretation"
fi
i=$((i + 1))
done
# Update last processed entry
if [ "$total_entries" -gt 0 ]; then
local last_datetime=$(jq -r '.[-1].datetime' "$QCAINFO_FILE" 2>/dev/null)
echo "$last_datetime" > "$LAST_ENTRY_FILE"
fi
}
# Check for new entries every 61 seconds
monitor_qcainfo() {
log_message "Starting network insights interpreter monitoring"
while true; do
# Acquire lock (OpenWrt compatible)
if (set -C; echo $$ > "$LOCKFILE") 2>/dev/null; then
trap 'rm -f "$LOCKFILE"; exit' INT TERM EXIT
process_qcainfo_data
# Release lock
rm -f "$LOCKFILE"
trap - INT TERM EXIT
else
log_message "Another instance is running, skipping this cycle"
fi
sleep 61
done
}
# Main execution
case "${1:-monitor}" in
"monitor")
monitor_qcainfo
;;
"process")
process_qcainfo_data
;;
*)
echo "Usage: $0 {monitor|process}"
echo " monitor - Run continuous monitoring (default)"
echo " process - Process current data once"
exit 1
;;
esac

View File

@@ -0,0 +1,137 @@
#!/bin/sh
set -eu
# Ensure PATH for OpenWrt/BusyBox
export PATH="/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
# Load centralized logging
. /www/cgi-bin/services/quecmanager_logger.sh
TMP_DIR="/tmp/quecmanager"
OUT_JSON="$TMP_DIR/ping_latency.json"
PID_FILE="$TMP_DIR/ping_daemon.pid"
CONFIG_FILE="/etc/quecmanager/settings/ping_settings.conf"
[ -f "$CONFIG_FILE" ] || CONFIG_FILE="/tmp/quecmanager/settings/ping_settings.conf"
DEFAULT_HOST="8.8.8.8"
DEFAULT_INTERVAL=5
SCRIPT_NAME="ping_daemon"
ensure_tmp_dir() { [ -d "$TMP_DIR" ] || mkdir -p "$TMP_DIR" || exit 1; }
log() {
qm_log_info "daemon" "$SCRIPT_NAME" "$1"
}
daemon_is_running() {
if [ -f "$PID_FILE" ]; then
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
# Avoid false positive if PID reused
if [ -r "/proc/$pid/cmdline" ] && grep -q "ping_daemon.sh" "/proc/$pid/cmdline" 2>/dev/null; then
return 0
else
rm -f "$PID_FILE" 2>/dev/null || true
fi
fi
fi
return 1
}
write_pid() { echo "$$" > "$PID_FILE"; }
cleanup() { rm -f "$PID_FILE" 2>/dev/null || true; }
read_config() {
ENABLED="true"; HOST="$DEFAULT_HOST"; INTERVAL="$DEFAULT_INTERVAL"
if [ -f "$CONFIG_FILE" ]; then
PING_ENABLED=$(grep -E "^PING_ENABLED=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2 | tr -d '\r') || true
PING_HOST=$(grep -E "^PING_HOST=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2 | tr -d '\r') || true
PING_INTERVAL=$(grep -E "^PING_INTERVAL=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2 | tr -d '\r') || true
case "${PING_ENABLED:-}" in true|1|on|yes|enabled) ENABLED=true ;; *) ENABLED=false ;; esac
[ -n "${PING_HOST:-}" ] && HOST="$PING_HOST"
if echo "${PING_INTERVAL:-}" | grep -qE '^[0-9]+$'; then
if [ "$PING_INTERVAL" -ge 1 ] && [ "$PING_INTERVAL" -le 3600 ]; then
INTERVAL="$PING_INTERVAL"
fi
fi
fi
}
# Create default config if none exists
create_default_config() {
local primary_config="/etc/quecmanager/settings/ping_settings.conf"
local fallback_config="/tmp/quecmanager/settings/ping_settings.conf"
# Check if either config exists
if [ -f "$primary_config" ] || [ -f "$fallback_config" ]; then
return 0
fi
# Try to create in primary location first
if mkdir -p "/etc/quecmanager/settings" 2>/dev/null; then
{
echo "PING_ENABLED=true"
echo "PING_HOST=$DEFAULT_HOST"
echo "PING_INTERVAL=$DEFAULT_INTERVAL"
} > "$primary_config" 2>/dev/null && {
chmod 644 "$primary_config" 2>/dev/null || true
CONFIG_FILE="$primary_config"
log "Created default config at $primary_config"
return 0
}
fi
# Fallback to tmp location
mkdir -p "/tmp/quecmanager/settings" 2>/dev/null || true
{
echo "PING_ENABLED=true"
echo "PING_HOST=$DEFAULT_HOST"
echo "PING_INTERVAL=$DEFAULT_INTERVAL"
} > "$fallback_config" && {
chmod 644 "$fallback_config" 2>/dev/null || true
CONFIG_FILE="$fallback_config"
log "Created default config at $fallback_config"
return 0
}
log "Failed to create default config file"
return 1
}
write_json_atomic() {
tmpfile="$(mktemp "$TMP_DIR/ping_latency.XXXXXX" 2>/dev/null || true)"
if [ -n "${tmpfile:-}" ] && [ -w "$TMP_DIR" ]; then
printf '%s' "$1" > "$tmpfile" 2>/dev/null || true
mv -f "$tmpfile" "$OUT_JSON" 2>/dev/null || printf '%s' "$1" > "$OUT_JSON"
else
printf '%s' "$1" > "$OUT_JSON"
fi
}
ensure_tmp_dir
log "Starting ping daemon"
if daemon_is_running; then log "Already running"; exit 0; fi
# Create default config if none exists
create_default_config
trap cleanup EXIT INT TERM
write_pid
while true; do
read_config
if [ "$ENABLED" != "true" ]; then log "Disabled in config"; exit 0; fi
ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
PING_BIN="$(command -v ping || echo /bin/ping)"
output="$("$PING_BIN" -c 1 -w 2 "$HOST" 2>/dev/null || true)"
if echo "$output" | grep -q "time="; then
latency_ms="$(echo "$output" | grep -o 'time=[0-9.]*' | head -n1 | cut -d'=' -f2 | cut -d'.' -f1)"; [ -z "$latency_ms" ] && latency_ms=0
json="{\"timestamp\":\"$ts\",\"host\":\"$HOST\",\"latency\":$latency_ms,\"ok\":true}"
else
json="{\"timestamp\":\"$ts\",\"host\":\"$HOST\",\"latency\":null,\"ok\":false}"
fi
write_json_atomic "$json"
log "Wrote: $json"
sleep "$INTERVAL"
done

View File

@@ -0,0 +1,119 @@
#!/bin/sh
# QuecManager Centralized Logging Helper
# OpenWrt/BusyBox compatible logging system
# Usage: source this file and use qm_log function
set -e
# Base log directory
QM_LOG_BASE="/tmp/quecmanager/logs"
# Log categories
QM_LOG_DAEMONS="$QM_LOG_BASE/daemons"
QM_LOG_SERVICES="$QM_LOG_BASE/services"
QM_LOG_SETTINGS="$QM_LOG_BASE/settings"
QM_LOG_SYSTEM="$QM_LOG_BASE/system"
# Log levels
QM_LOG_ERROR="ERROR"
QM_LOG_WARN="WARN"
QM_LOG_INFO="INFO"
QM_LOG_DEBUG="DEBUG"
# Maximum log file size (in KB) - keep small for OpenWrt
QM_LOG_MAX_SIZE=500
# Initialize log directories
qm_init_logs() {
mkdir -p "$QM_LOG_DAEMONS" "$QM_LOG_SERVICES" "$QM_LOG_SETTINGS" "$QM_LOG_SYSTEM" 2>/dev/null || true
}
# Get log file path based on category and script name
qm_get_logfile() {
local category="$1"
local script_name="$2"
case "$category" in
"daemon"|"daemons")
echo "$QM_LOG_DAEMONS/${script_name}.log"
;;
"service"|"services")
echo "$QM_LOG_SERVICES/${script_name}.log"
;;
"setting"|"settings")
echo "$QM_LOG_SETTINGS/${script_name}.log"
;;
"system")
echo "$QM_LOG_SYSTEM/${script_name}.log"
;;
*)
echo "$QM_LOG_SYSTEM/unknown.log"
;;
esac
}
# Simple log rotation - keep it OpenWrt compatible
qm_rotate_log() {
local logfile="$1"
if [ -f "$logfile" ]; then
# Get file size in KB (use du for BusyBox compatibility)
local size_kb=$(du -k "$logfile" 2>/dev/null | cut -f1)
if [ "${size_kb:-0}" -gt "$QM_LOG_MAX_SIZE" ]; then
# Simple rotation: keep last 2 versions
[ -f "${logfile}.1" ] && mv "${logfile}.1" "${logfile}.2" 2>/dev/null || true
mv "$logfile" "${logfile}.1" 2>/dev/null || true
touch "$logfile" 2>/dev/null || true
fi
fi
}
# Main logging function
# Usage: qm_log "category" "script_name" "level" "message"
qm_log() {
local category="$1"
local script_name="$2"
local level="$3"
local message="$4"
# Initialize if needed
qm_init_logs
# Get log file path
local logfile=$(qm_get_logfile "$category" "$script_name")
# Rotate if needed
qm_rotate_log "$logfile"
# Create log entry with OpenWrt compatible date
local timestamp=$(date '+%Y-%m-%d %H:%M:%S' 2>/dev/null || date)
local pid="$$"
# Write log entry
printf '[%s] [%s] [%s] [PID:%s] %s\n' "$timestamp" "$level" "$script_name" "$pid" "$message" >> "$logfile" 2>/dev/null || true
}
# Convenience functions for different log levels
qm_log_error() {
qm_log "$1" "$2" "$QM_LOG_ERROR" "$3"
}
qm_log_warn() {
qm_log "$1" "$2" "$QM_LOG_WARN" "$3"
}
qm_log_info() {
qm_log "$1" "$2" "$QM_LOG_INFO" "$3"
}
qm_log_debug() {
qm_log "$1" "$2" "$QM_LOG_DEBUG" "$3"
}
# Cleanup old logs (called periodically)
qm_cleanup_logs() {
# Remove .2 backup files older than 1 day to save space
find "$QM_LOG_BASE" -name "*.2" -type f -mtime +1 -delete 2>/dev/null || true
}

View File

@@ -2,6 +2,9 @@
# 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"
@@ -15,25 +18,49 @@ 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 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"
# 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"
# Function to log messages
# 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
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"
# Function to log messages - now uses centralized logging
log_message() {
local message="$1"
local level="${2:-info}"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
# Log to system log
# 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 quecprofiles_daemon -p "daemon.$level" "$message"
# Log to debug file
# Log to debug file (maintain existing behavior)
echo "[$timestamp] [$level] $message" >>"$DEBUG_LOG"
# For detailed logs or errors
# For detailed logs or errors (maintain existing behavior)
if [ "$level" = "error" ] || [ "$level" = "debug" ]; then
echo "[$timestamp] [$level] $message" >>"$DETAILED_LOG"
fi
@@ -607,6 +634,7 @@ apply_profile_settings() {
local current_nsa_nr5g_bands="${14}"
local current_imei="${15}"
local iccid="${16}"
local mobile_provider="${17}"
# Set TTL to 0 (disabled) if not specified
ttl="${ttl:-0}"
@@ -619,6 +647,7 @@ apply_profile_settings() {
log_message "- APN: $apn ($pdp_type)" "info"
log_message "- IMEI: $imei" "info"
log_message "- TTL: $ttl" "info"
log_message "- Mobile Provider: $mobile_provider" "info"
# Check if any changes are needed using improved comparison
local needs_apn_change=0
@@ -630,6 +659,7 @@ apply_profile_settings() {
local needs_ttl_change=0
local changes_needed=0
local requires_reboot=0
local change_for_reboot=""
# Use normalized comparison
compare_values "$current_apn" "$apn" "apn" && needs_apn_change=1 && changes_needed=1
@@ -804,6 +834,7 @@ apply_profile_settings() {
if [ $? -eq 0 ]; then
changes_made=1
requires_reboot=1
change_for_reboot="IMEI"
log_message "IMEI changed successfully to $imei (device will reboot)" "info"
update_track "rebooting" "IMEI changed, device will reboot" "$profile_name" "95"
else
@@ -813,9 +844,56 @@ apply_profile_settings() {
fi
fi
# Apply unique rule setup for Verizon, but also handle "Other" Mobile Providers because of MPDN_rule shenanigans
# Probably requires reboot
output_check=$(execute_at_command "AT+QMAP=\"mpdn_rule\"")
sleep 1 # Short delay to ensure command is processed
qmap_rule0=$(echo "$output_check" | grep '+QMAP: "MPDN_rule",0,')
qmap_ippt_rule0=$(echo "$qmap_rule0" | cut -d',' -f5)
if [ $apply_success -eq 1 ] && [ -n "$mobile_provider" ]; then
if [ "$mobile_provider" = "Verizon" ]; then
# If Verizon, data call should be set to rule 3, AT+QMAP="mpdn_rule",0,3,0,0,1
if echo "$qmap_rule0" | awk -F',' '{exit !($2==0 && $3==3 && $6==1)}'; then
log_message "Verizon rule already set correctly, no changes needed" "info"
else
log_message "Setting Verizon data call mpdn_rule to 3" "info"
update_track "applying" "Setting Verizon data call rule to 3" "$profile_name" "100"
verizon_cmd="AT+QMAP=\"mpdn_rule\",0,3,0,$qmap_ippt_rule0,1"
execute_at_command "$verizon_cmd" 10 "$token_id" >/dev/null
sleep 1 # Short delay to ensure command is processed
fi
elif [ "$mobile_provider" = "Other" ]; then
# Check if MPDN_rule 0 is already set to all zeros
if echo "$qmap_rule0" | awk -F',' '{exit !($2==0 && $3==0 && $6==0)}'; then
log_message "Default rule already set correctly, no changes needed" "info"
else
log_message "Setting to default mpdn_rule and releasing" "info"
update_track "applying" "Setting Default data call mpdn_rule to 0" "$profile_name" "100"
def_cmd1="AT+QMAP=\"mpdn_rule\",0"
execute_at_command "$def_cmd1" 10 "$token_id"
sleep 1 # Short delay to ensure command is processed
def_cmd2="AT+QMAP=\"mpdn_rule\",0,1,0,$qmap_ippt_rule0,1"
execute_at_command "$def_cmd2" 10 "$token_id"
sleep 1 # Short delay to ensure command is processed
if [ "$qmap_ippt_rule0" = "0" ]; then
log_message "IPPT is disabled for rule, release the MPDN_rule" "info"
def_cmd3="AT+QMAP=\"mpdn_rule\",0"
execute_at_command "$def_cmd3" 10 "$token_id"
sleep 1 # Short delay to ensure command is processed
if [ "$(cat /sys/devices/soc0/machine)" = "SDXPINN" ]; then
requires_reboot=1
change_for_reboot="MPDN_rule"
update_track "rebooting" "MPDN_rule released, device will reboot" "$profile_name" "105"
fi
else
log_message "IPPT is enabled for rule0 not releasing MPDN_rule, no reboot needed: IPPT Value $qmap_ippt_rule0" "info"
fi
fi
fi
fi
# Release token
release_token "$token_id"
# Mark profile as applied if changes were made
if [ $changes_made -eq 1 ]; then
mark_profile_applied "$iccid" "$profile_name"
@@ -824,7 +902,7 @@ apply_profile_settings() {
# If IMEI was changed, need to reboot
if [ $requires_reboot -eq 1 ]; then
log_message "IMEI change requires reboot, scheduling reboot..." "info"
update_track "rebooting" "Device is rebooting to apply IMEI change" "$profile_name" "100"
update_track "rebooting" "Device is rebooting to apply $change_for_reboot change" "$profile_name" "100"
sleep 2
reboot &
return 0
@@ -913,11 +991,12 @@ check_profile() {
local pdp_type=$(uci -q get quecprofiles.$profile_index.pdp_type)
local imei=$(uci -q get quecprofiles.$profile_index.imei)
local ttl=$(uci -q get quecprofiles.$profile_index.ttl)
local mobile_provider=$(uci -q get quecprofiles.$profile_index.mobile_provider)
# Check if profile is paused
local paused=$(uci -q get quecprofiles.$profile_index.paused)
paused="${paused:-0}" # Default to not paused if not set
# Skip applying paused profiles
if [ "$paused" = "1" ]; then
log_message "Profile '$profile_name' is paused, skipping application" "info"
@@ -982,7 +1061,7 @@ check_profile() {
# Apply profile settings with the new parameters
apply_profile_settings "$profile_name" "$network_type" "$lte_bands" "$sa_nr5g_bands" "$nsa_nr5g_bands" \
"$apn" "$pdp_type" "$imei" "$ttl" "$current_apn" "$current_mode" "$current_lte_bands" \
"$current_sa_nr5g_bands" "$current_nsa_nr5g_bands" "$current_imei" "$current_iccid"
"$current_sa_nr5g_bands" "$current_nsa_nr5g_bands" "$current_imei" "$current_iccid" "$mobile_provider"
return $?
else
log_message "Automatic profile switching is disabled, not applying profile" "info"
@@ -1038,7 +1117,7 @@ main() {
while [ $sleep_counter -lt $check_interval ]; do
sleep 5
sleep_counter=$((sleep_counter + 5))
# Check for manual trigger during sleep
if [ -f "$CHECK_TRIGGER" ]; then
log_message "Manual check triggered during sleep" "info"

View File

@@ -3,6 +3,9 @@
# 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
@@ -17,6 +20,7 @@ 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"
@@ -25,17 +29,33 @@ mkdir -p "$LOG_DIR" "$QUEUE_DIR"
echo "$$" > "$PID_FILE"
chmod 644 "$PID_FILE"
# Function to log messages
# Function to log messages - now uses centralized logging
log_message() {
local level="${2:-info}"
local message="$1"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
# Log to file
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
# 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
# Log to system log
# Also maintain system logging for compatibility
logger -t quecwatch -p "daemon.$level" "$message"
# Log to file (maintain existing behavior)
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
}
# Function to update status