QuecManager non-beta
Its about time I did this!
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Initialize error tracking
|
||||
has_error=false
|
||||
error_message=""
|
||||
|
||||
# Function to append to error message
|
||||
append_error() {
|
||||
if [ -z "$error_message" ]; then
|
||||
error_message="$1"
|
||||
else
|
||||
error_message="$error_message; $1"
|
||||
fi
|
||||
has_error=true
|
||||
}
|
||||
|
||||
# Function to log cleanup events
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local LOG_DIR="/tmp/log/apnprofile"
|
||||
local LOG_FILE="${LOG_DIR}/apnprofile.log"
|
||||
|
||||
# Ensure log directory exists
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "${timestamp} - [${level}] ${message}" >> "$LOG_FILE"
|
||||
logger -t apnprofile "${level}: ${message}"
|
||||
}
|
||||
|
||||
log_message "INFO" "Starting APN Profile cleanup process"
|
||||
|
||||
# Stop and disable the service
|
||||
if [ -f "/etc/init.d/apnprofile-service" ]; then
|
||||
if /etc/init.d/apnprofile-service stop; then
|
||||
log_message "INFO" "APN Profile service stopped"
|
||||
else
|
||||
append_error "Failed to stop APN Profile service"
|
||||
log_message "ERROR" "Failed to stop APN Profile service"
|
||||
fi
|
||||
|
||||
if /etc/init.d/apnprofile-service disable; then
|
||||
log_message "INFO" "APN Profile service disabled"
|
||||
else
|
||||
append_error "Failed to disable APN Profile service"
|
||||
log_message "ERROR" "Failed to disable APN Profile service"
|
||||
fi
|
||||
|
||||
# Remove the init.d script
|
||||
if rm -f "/etc/init.d/apnprofile-service"; then
|
||||
log_message "INFO" "Removed init.d script"
|
||||
else
|
||||
append_error "Failed to remove init.d script"
|
||||
log_message "ERROR" "Failed to remove init.d script"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove service script
|
||||
if [ -f "/www/cgi-bin/services/apnprofile.sh" ]; then
|
||||
if rm -f "/www/cgi-bin/services/apnprofile.sh"; then
|
||||
log_message "INFO" "Removed service script"
|
||||
else
|
||||
append_error "Failed to remove service script"
|
||||
log_message "ERROR" "Failed to remove service script"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove symlinks in rc.d if they exist
|
||||
for link in /etc/rc.d/S??apnprofile-service /etc/rc.d/K??apnprofile-service; do
|
||||
if [ -L "$link" ]; then
|
||||
if rm -f "$link"; then
|
||||
log_message "INFO" "Removed rc.d symlink: $link"
|
||||
else
|
||||
append_error "Failed to remove rc.d symlink: $link"
|
||||
log_message "ERROR" "Failed to remove rc.d symlink: $link"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove UCI configuration (only removes apn_profile section, leaves other sections intact)
|
||||
if uci -q get quecmanager.apn_profile >/dev/null; then
|
||||
if uci delete quecmanager.apn_profile && uci commit quecmanager; then
|
||||
log_message "INFO" "Removed UCI configuration"
|
||||
else
|
||||
append_error "Failed to remove UCI configuration"
|
||||
log_message "ERROR" "Failed to remove UCI configuration"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Kill any remaining processes
|
||||
if pkill -f "/www/cgi-bin/services/apnprofile.sh"; then
|
||||
log_message "INFO" "Killed remaining APN Profile processes"
|
||||
fi
|
||||
|
||||
# Clean up temporary files
|
||||
for file in \
|
||||
"/tmp/at_pipe.txt" \
|
||||
"/var/run/apnprofile.pid" \
|
||||
"/tmp/apn_result.txt" \
|
||||
"/tmp/debug.log" \
|
||||
"/tmp/inputICCID.txt" \
|
||||
"/tmp/outputICCID.txt" \
|
||||
"/tmp/inputAPN.txt" \
|
||||
"/tmp/outputAPN.txt"
|
||||
do
|
||||
if [ -f "$file" ]; then
|
||||
if rm -f "$file"; then
|
||||
log_message "INFO" "Removed temporary file: $file"
|
||||
else
|
||||
append_error "Failed to remove temporary file: $file"
|
||||
log_message "ERROR" "Failed to remove temporary file: $file"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
log_message "INFO" "APN Profile cleanup completed"
|
||||
|
||||
# Return appropriate JSON response
|
||||
if [ "$has_error" = true ]; then
|
||||
echo "{\"status\": \"error\", \"message\": \"$error_message\"}"
|
||||
else
|
||||
echo "{\"status\": \"success\", \"message\": \"APN Profile service successfully removed\"}"
|
||||
fi
|
||||
@@ -0,0 +1,144 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Set headers for JSON response
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Load UCI functions
|
||||
. /lib/functions.sh
|
||||
|
||||
# Function to safely get UCI value with default
|
||||
get_uci_value() {
|
||||
local value
|
||||
config_get value apn_profile "$1" "$2"
|
||||
echo "${value:-$2}"
|
||||
}
|
||||
|
||||
# Function to check if service is running
|
||||
check_service_status() {
|
||||
if [ -f "/var/run/apnprofile.pid" ]; then
|
||||
pid=$(cat /var/run/apnprofile.pid)
|
||||
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||
echo "running"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# Double check using process search
|
||||
if pgrep -f "/www/cgi-bin/services/apnprofile.sh" >/dev/null; then
|
||||
echo "running"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "stopped"
|
||||
}
|
||||
|
||||
# Function to get last log entry
|
||||
get_last_log() {
|
||||
local LOG_FILE="/tmp/log/apnprofile/apnprofile.log"
|
||||
if [ -f "$LOG_FILE" ]; then
|
||||
tail -n 1 "$LOG_FILE"
|
||||
else
|
||||
echo "No log entries found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if init.d service is enabled
|
||||
check_service_enabled() {
|
||||
if [ -f "/etc/init.d/apnprofile-service" ]; then
|
||||
if /etc/init.d/apnprofile-service enabled; then
|
||||
echo "true"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
echo "false"
|
||||
}
|
||||
|
||||
# Load QuecManager configuration
|
||||
config_load quecmanager
|
||||
|
||||
# Check if APN Profile section exists
|
||||
if ! uci -q get quecmanager.apn_profile >/dev/null; then
|
||||
echo '{"status": "inactive", "message": "APN Profile service is not configured"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get enabled status from UCI
|
||||
enabled=$(get_uci_value "enabled" "0")
|
||||
|
||||
if [ "$enabled" != "1" ]; then
|
||||
echo '{"status": "inactive", "message": "APN Profile service is disabled"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if service script exists
|
||||
if [ ! -f "/www/cgi-bin/services/apnprofile.sh" ]; then
|
||||
echo '{"status": "error", "message": "Service script is missing"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get service status information
|
||||
service_status=$(check_service_status)
|
||||
service_enabled=$(check_service_enabled)
|
||||
last_log=$(get_last_log)
|
||||
|
||||
# Fetch all configuration values from UCI
|
||||
iccid_profile1=$(get_uci_value "iccid_profile1" "")
|
||||
apn_profile1=$(get_uci_value "apn_profile1" "")
|
||||
pdp_type1=$(get_uci_value "pdp_type1" "")
|
||||
iccid_profile2=$(get_uci_value "iccid_profile2" "")
|
||||
apn_profile2=$(get_uci_value "apn_profile2" "")
|
||||
pdp_type2=$(get_uci_value "pdp_type2" "")
|
||||
|
||||
# Function to check if profile data exists
|
||||
validate_profile_data() {
|
||||
local iccid="$1"
|
||||
local apn="$2"
|
||||
local pdp="$3"
|
||||
|
||||
[ -n "$iccid" ] && [ -n "$apn" ] && [ -n "$pdp" ]
|
||||
}
|
||||
|
||||
# Build JSON response
|
||||
cat <<EOF
|
||||
{
|
||||
"status": "active",
|
||||
"service": {
|
||||
"status": "${service_status}",
|
||||
"enabled": ${service_enabled},
|
||||
"script": "$([ -f "/www/cgi-bin/services/apnprofile.sh" ] && echo "present" || echo "missing")",
|
||||
"initScript": "$([ -f "/etc/init.d/apnprofile-service" ] && echo "present" || echo "missing")"
|
||||
},
|
||||
"profiles": {
|
||||
EOF
|
||||
|
||||
# Add Profile 1 if it exists
|
||||
if validate_profile_data "$iccid_profile1" "$apn_profile1" "$pdp_type1"; then
|
||||
cat <<EOF
|
||||
"profile1": {
|
||||
"iccid": "${iccid_profile1}",
|
||||
"apn": "${apn_profile1}",
|
||||
"pdpType": "${pdp_type1}"
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Add Profile 2 if it exists
|
||||
if validate_profile_data "$iccid_profile2" "$apn_profile2" "$pdp_type2"; then
|
||||
# Add comma if Profile 1 was added
|
||||
[ -n "$iccid_profile1" ] && echo ","
|
||||
cat <<EOF
|
||||
"profile2": {
|
||||
"iccid": "${iccid_profile2}",
|
||||
"apn": "${apn_profile2}",
|
||||
"pdpType": "${pdp_type2}"
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Close the profiles object and add last activity
|
||||
cat <<EOF
|
||||
},
|
||||
"lastActivity": "${last_log}"
|
||||
}
|
||||
EOF
|
||||
@@ -0,0 +1,345 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Read POST data
|
||||
read -r QUERY_STRING
|
||||
|
||||
# Function to urldecode
|
||||
urldecode() {
|
||||
local value="$1"
|
||||
value="${value//+/ }"
|
||||
value="${value//%/\\x}"
|
||||
printf '%b' "$value"
|
||||
}
|
||||
|
||||
# Extract values from POST data
|
||||
iccidProfile1=$(echo "$QUERY_STRING" | sed -n 's/.*iccidProfile1=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
apnProfile1=$(echo "$QUERY_STRING" | sed -n 's/.*apnProfile1=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
pdpType1=$(echo "$QUERY_STRING" | sed -n 's/.*pdpType1=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
iccidProfile2=$(echo "$QUERY_STRING" | sed -n 's/.*iccidProfile2=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
apnProfile2=$(echo "$QUERY_STRING" | sed -n 's/.*apnProfile2=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
pdpType2=$(echo "$QUERY_STRING" | sed -n 's/.*pdpType2=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
|
||||
# URL decode the values
|
||||
iccidProfile1=$(urldecode "$iccidProfile1")
|
||||
apnProfile1=$(urldecode "$apnProfile1")
|
||||
pdpType1=$(urldecode "$pdpType1")
|
||||
iccidProfile2=$(urldecode "$iccidProfile2")
|
||||
apnProfile2=$(urldecode "$apnProfile2")
|
||||
pdpType2=$(urldecode "$pdpType2")
|
||||
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Validate required first profile
|
||||
if [ -z "$iccidProfile1" ] || [ -z "$apnProfile1" ] || [ -z "$pdpType1" ]; then
|
||||
echo '{"status": "error", "message": "Profile 1 is required"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local LOG_DIR="/tmp/log/apnprofile"
|
||||
local LOG_FILE="${LOG_DIR}/apnprofile.log"
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "${timestamp} - [${level}] ${message}" >> "$LOG_FILE"
|
||||
logger -t apnprofile "${level}: ${message}"
|
||||
}
|
||||
|
||||
# Create required directories
|
||||
mkdir -p /www/cgi-bin/services
|
||||
mkdir -p /etc/init.d
|
||||
|
||||
# Function to create service script
|
||||
create_service_script() {
|
||||
cat > /www/cgi-bin/services/apnprofile.sh <<'EOL'
|
||||
#!/bin/sh
|
||||
|
||||
# Load UCI functions
|
||||
. /lib/functions.sh
|
||||
|
||||
# Define file paths
|
||||
QUEUE_FILE="/tmp/at_pipe.txt"
|
||||
LOG_DIR="/tmp/log/apnprofile"
|
||||
LOG_FILE="${LOG_DIR}/apnprofile.log"
|
||||
PID_FILE="/var/run/apnprofile.pid"
|
||||
STATE_FILE="/tmp/apnprofile_state.json"
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
[ ! -f "${QUEUE_FILE}" ] && touch "${QUEUE_FILE}"
|
||||
|
||||
# Save PID
|
||||
echo $$ > "${PID_FILE}"
|
||||
|
||||
# Enhanced logging function
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "${timestamp} - [${level}] ${message}" >> "$LOG_FILE"
|
||||
logger -t apnprofile "${level}: ${message}"
|
||||
}
|
||||
|
||||
# AT command handling with locking
|
||||
handle_lock() {
|
||||
local max_wait=30
|
||||
local wait_count=0
|
||||
|
||||
while [ -f "$QUEUE_FILE" ] && grep -q "AT_COMMAND" "$QUEUE_FILE" && [ $wait_count -lt $max_wait ]; do
|
||||
sleep 1
|
||||
wait_count=$((wait_count + 1))
|
||||
done
|
||||
|
||||
printf '{"command":"AT_COMMAND","pid":"%s","timestamp":"%s"}\n' "$$" "$(date '+%H:%M:%S')" >> "$QUEUE_FILE"
|
||||
}
|
||||
|
||||
# Execute AT command with retries
|
||||
execute_at_command() {
|
||||
local command="$1"
|
||||
local result=""
|
||||
local retry_count=0
|
||||
local max_retries=3
|
||||
|
||||
while [ $retry_count -lt $max_retries ]; do
|
||||
handle_lock
|
||||
result=$(sms_tool at "$command" -t 4 2>&1)
|
||||
local status=$?
|
||||
sed -i "/\"pid\":\"$$\"/d" "$QUEUE_FILE"
|
||||
|
||||
if [ $status -eq 0 ] && [ -n "$result" ]; then
|
||||
echo "$result"
|
||||
return 0
|
||||
fi
|
||||
|
||||
retry_count=$((retry_count + 1))
|
||||
[ $retry_count -lt $max_retries ] && sleep 2
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Get current ICCID
|
||||
get_current_iccid() {
|
||||
local result=$(execute_at_command "AT+ICCID")
|
||||
if [ $? -eq 0 ] && echo "$result" | grep -q "+ICCID:"; then
|
||||
echo "$result" | grep "+ICCID:" | cut -d' ' -f2 | tr -d '[:space:]'
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Set APN with error handling
|
||||
set_apn() {
|
||||
local pdp_type="$1"
|
||||
local apn="$2"
|
||||
|
||||
if [ -z "$pdp_type" ] || [ -z "$apn" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if execute_at_command "AT+CGDCONT=1,\"$pdp_type\",\"$apn\";+COPS=2;+COPS=0"; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to get current configuration hash
|
||||
get_config_hash() {
|
||||
config_load quecmanager
|
||||
local hash_input=""
|
||||
|
||||
# Get Profile 1
|
||||
config_get ICCID_PROFILE1 apn_profile iccid_profile1
|
||||
config_get APN_PROFILE1 apn_profile apn_profile1
|
||||
config_get PDP_TYPE1 apn_profile pdp_type1
|
||||
|
||||
# Get Profile 2
|
||||
config_get ICCID_PROFILE2 apn_profile iccid_profile2
|
||||
config_get APN_PROFILE2 apn_profile apn_profile2
|
||||
config_get PDP_TYPE2 apn_profile pdp_type2
|
||||
|
||||
hash_input="${ICCID_PROFILE1}${APN_PROFILE1}${PDP_TYPE1}${ICCID_PROFILE2}${APN_PROFILE2}${PDP_TYPE2}"
|
||||
echo "$hash_input" | md5sum | cut -d' ' -f1
|
||||
}
|
||||
|
||||
# Function to read state file
|
||||
read_state() {
|
||||
if [ -f "$STATE_FILE" ]; then
|
||||
cat "$STATE_FILE"
|
||||
else
|
||||
echo "{}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to write state file
|
||||
write_state() {
|
||||
local current_iccid="$1"
|
||||
local config_hash="$2"
|
||||
local status="$3"
|
||||
|
||||
printf '{"iccid":"%s","config_hash":"%s","status":"%s","timestamp":"%s"}' \
|
||||
"$current_iccid" "$config_hash" "$status" "$(date '+%Y-%m-%d %H:%M:%S')" > "$STATE_FILE"
|
||||
}
|
||||
|
||||
# Main service loop
|
||||
while true; do
|
||||
# Get current state
|
||||
current_state=$(read_state)
|
||||
current_iccid=$(get_current_iccid)
|
||||
config_hash=$(get_config_hash)
|
||||
|
||||
# Extract values from current state
|
||||
state_iccid=$(echo "$current_state" | sed -n 's/.*"iccid":"\([^"]*\)".*/\1/p')
|
||||
state_hash=$(echo "$current_state" | sed -n 's/.*"config_hash":"\([^"]*\)".*/\1/p')
|
||||
|
||||
needs_update=0
|
||||
|
||||
# Check if update is needed
|
||||
if [ ! -f "$STATE_FILE" ]; then
|
||||
log_message "INFO" "No state file found, will apply profile"
|
||||
needs_update=1
|
||||
elif [ "$current_iccid" != "$state_iccid" ]; then
|
||||
log_message "INFO" "ICCID changed from $state_iccid to $current_iccid"
|
||||
needs_update=1
|
||||
elif [ "$config_hash" != "$state_hash" ]; then
|
||||
log_message "INFO" "Configuration changed"
|
||||
needs_update=1
|
||||
fi
|
||||
|
||||
if [ $needs_update -eq 1 ] && [ -n "$current_iccid" ]; then
|
||||
config_load quecmanager
|
||||
|
||||
# Get Profile 1
|
||||
config_get ICCID_PROFILE1 apn_profile iccid_profile1
|
||||
config_get APN_PROFILE1 apn_profile apn_profile1
|
||||
config_get PDP_TYPE1 apn_profile pdp_type1
|
||||
|
||||
# Get Profile 2
|
||||
config_get ICCID_PROFILE2 apn_profile iccid_profile2
|
||||
config_get APN_PROFILE2 apn_profile apn_profile2
|
||||
config_get PDP_TYPE2 apn_profile pdp_type2
|
||||
|
||||
if [ "${current_iccid}" = "${ICCID_PROFILE1}" ]; then
|
||||
if set_apn "$PDP_TYPE1" "$APN_PROFILE1"; then
|
||||
log_message "INFO" "Successfully applied Profile 1"
|
||||
write_state "$current_iccid" "$config_hash" "success"
|
||||
else
|
||||
log_message "ERROR" "Failed to apply Profile 1"
|
||||
write_state "$current_iccid" "$config_hash" "error"
|
||||
fi
|
||||
elif [ -n "$ICCID_PROFILE2" ] && [ "${current_iccid}" = "${ICCID_PROFILE2}" ]; then
|
||||
if set_apn "$PDP_TYPE2" "$APN_PROFILE2"; then
|
||||
log_message "INFO" "Successfully applied Profile 2"
|
||||
write_state "$current_iccid" "$config_hash" "success"
|
||||
else
|
||||
log_message "ERROR" "Failed to apply Profile 2"
|
||||
write_state "$current_iccid" "$config_hash" "error"
|
||||
fi
|
||||
else
|
||||
log_message "INFO" "No matching ICCID profile found"
|
||||
write_state "$current_iccid" "$config_hash" "no_match"
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep 10
|
||||
done
|
||||
EOL
|
||||
|
||||
chmod 755 /www/cgi-bin/services/apnprofile.sh
|
||||
}
|
||||
|
||||
# Function to create init.d script
|
||||
create_init_script() {
|
||||
cat > /etc/init.d/apnprofile-service <<'EOL'
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
local enabled
|
||||
|
||||
# Check if service is enabled in UCI
|
||||
config_load quecmanager
|
||||
config_get enabled apn_profile enabled '0'
|
||||
|
||||
[ "$enabled" != "1" ] && return 0
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /www/cgi-bin/services/apnprofile.sh
|
||||
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param nice 19
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "quecmanager"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
EOL
|
||||
|
||||
chmod 755 /etc/init.d/apnprofile-service
|
||||
}
|
||||
|
||||
# Initialize UCI configuration
|
||||
touch /etc/config/quecmanager
|
||||
|
||||
# Remove existing APN profile section if it exists
|
||||
uci -q delete quecmanager.apn_profile
|
||||
|
||||
# Create new APN profile section
|
||||
uci set quecmanager.apn_profile=service
|
||||
uci set quecmanager.apn_profile.enabled=1
|
||||
|
||||
# Set Profile 1 configuration
|
||||
uci set quecmanager.apn_profile.iccid_profile1="$iccidProfile1"
|
||||
uci set quecmanager.apn_profile.apn_profile1="$apnProfile1"
|
||||
uci set quecmanager.apn_profile.pdp_type1="$pdpType1"
|
||||
|
||||
# Set Profile 2 configuration if provided
|
||||
if [ -n "$iccidProfile2" ]; then
|
||||
uci set quecmanager.apn_profile.iccid_profile2="$iccidProfile2"
|
||||
uci set quecmanager.apn_profile.apn_profile2="$apnProfile2"
|
||||
uci set quecmanager.apn_profile.pdp_type2="$pdpType2"
|
||||
fi
|
||||
|
||||
# Commit UCI changes
|
||||
if ! uci commit quecmanager; then
|
||||
log_message "ERROR" "Failed to save UCI configuration"
|
||||
echo '{"status": "error", "message": "Failed to save UCI configuration"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_message "INFO" "UCI configuration saved successfully"
|
||||
|
||||
# Create service script if it doesn't exist
|
||||
if [ ! -f "/www/cgi-bin/services/apnprofile.sh" ]; then
|
||||
create_service_script
|
||||
log_message "INFO" "Created service script"
|
||||
fi
|
||||
|
||||
# Create init.d script if it doesn't exist
|
||||
if [ ! -f "/etc/init.d/apnprofile-service" ]; then
|
||||
create_init_script
|
||||
log_message "INFO" "Created init.d script"
|
||||
fi
|
||||
|
||||
# Enable and start the service
|
||||
/etc/init.d/apnprofile-service enable
|
||||
if /etc/init.d/apnprofile-service restart; then
|
||||
log_message "INFO" "Service started successfully"
|
||||
echo '{"status": "success", "message": "APN profiles saved and service started"}'
|
||||
else
|
||||
log_message "ERROR" "Failed to start service"
|
||||
echo '{"status": "error", "message": "Failed to start service"}'
|
||||
fi
|
||||
@@ -0,0 +1,127 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Initialize error tracking
|
||||
has_error=false
|
||||
error_message=""
|
||||
|
||||
# Function to append to error message
|
||||
append_error() {
|
||||
if [ -z "$error_message" ]; then
|
||||
error_message="$1"
|
||||
else
|
||||
error_message="$error_message; $1"
|
||||
fi
|
||||
has_error=true
|
||||
}
|
||||
|
||||
# Function to log cleanup events
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local LOG_DIR="/tmp/log/imeiprofile"
|
||||
local LOG_FILE="${LOG_DIR}/imeiprofile.log"
|
||||
|
||||
# Ensure log directory exists
|
||||
mkdir -p "${LOG_DIR}"
|
||||
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "${timestamp} - [${level}] ${message}" >> "$LOG_FILE"
|
||||
logger -t imeiprofile "${level}: ${message}"
|
||||
}
|
||||
|
||||
log_message "INFO" "Starting IMEI Profile cleanup process"
|
||||
|
||||
# Stop and disable the service
|
||||
if [ -f "/etc/init.d/imeiprofile-service" ]; then
|
||||
if /etc/init.d/imeiprofile-service stop; then
|
||||
log_message "INFO" "IMEI Profile service stopped"
|
||||
else
|
||||
append_error "Failed to stop IMEI Profile service"
|
||||
log_message "ERROR" "Failed to stop IMEI Profile service"
|
||||
fi
|
||||
|
||||
if /etc/init.d/imeiprofile-service disable; then
|
||||
log_message "INFO" "IMEI Profile service disabled"
|
||||
else
|
||||
append_error "Failed to disable IMEI Profile service"
|
||||
log_message "ERROR" "Failed to disable IMEI Profile service"
|
||||
fi
|
||||
|
||||
# Remove the init.d script
|
||||
if rm -f "/etc/init.d/imeiprofile-service"; then
|
||||
log_message "INFO" "Removed init.d script"
|
||||
else
|
||||
append_error "Failed to remove init.d script"
|
||||
log_message "ERROR" "Failed to remove init.d script"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove service script
|
||||
if [ -f "/www/cgi-bin/services/imeiprofile.sh" ]; then
|
||||
if rm -f "/www/cgi-bin/services/imeiprofile.sh"; then
|
||||
log_message "INFO" "Removed service script"
|
||||
else
|
||||
append_error "Failed to remove service script"
|
||||
log_message "ERROR" "Failed to remove service script"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove symlinks in rc.d if they exist
|
||||
for link in /etc/rc.d/S??imeiprofile-service /etc/rc.d/K??imeiprofile-service; do
|
||||
if [ -L "$link" ]; then
|
||||
if rm -f "$link"; then
|
||||
log_message "INFO" "Removed rc.d symlink: $link"
|
||||
else
|
||||
append_error "Failed to remove rc.d symlink: $link"
|
||||
log_message "ERROR" "Failed to remove rc.d symlink: $link"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Remove UCI configuration
|
||||
if uci -q get quecmanager.imei_profile >/dev/null; then
|
||||
if uci delete quecmanager.imei_profile && uci commit quecmanager; then
|
||||
log_message "INFO" "Removed UCI configuration"
|
||||
else
|
||||
append_error "Failed to remove UCI configuration"
|
||||
log_message "ERROR" "Failed to remove UCI configuration"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Kill any remaining processes
|
||||
if pkill -f "/www/cgi-bin/services/imeiprofile.sh"; then
|
||||
log_message "INFO" "Killed remaining IMEI Profile processes"
|
||||
fi
|
||||
|
||||
# Clean up temporary files
|
||||
for file in \
|
||||
"/tmp/at_pipe.txt" \
|
||||
"/var/run/imeiprofile.pid" \
|
||||
"/tmp/imei_result.txt" \
|
||||
"/tmp/debug.log" \
|
||||
"/tmp/inputICCID.txt" \
|
||||
"/tmp/outputICCID.txt" \
|
||||
"/tmp/inputIMEI.txt" \
|
||||
"/tmp/outputIMEI.txt"
|
||||
do
|
||||
if [ -f "$file" ]; then
|
||||
if rm -f "$file"; then
|
||||
log_message "INFO" "Removed temporary file: $file"
|
||||
else
|
||||
append_error "Failed to remove temporary file: $file"
|
||||
log_message "ERROR" "Failed to remove temporary file: $file"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
log_message "INFO" "IMEI Profile cleanup completed"
|
||||
|
||||
# Return appropriate JSON response
|
||||
if [ "$has_error" = true ]; then
|
||||
echo "{\"status\": \"error\", \"message\": \"$error_message\"}"
|
||||
else
|
||||
echo "{\"status\": \"success\", \"message\": \"IMEI Profile service successfully removed\"}"
|
||||
fi
|
||||
@@ -0,0 +1,138 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Set headers for JSON response
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Load UCI functions
|
||||
. /lib/functions.sh
|
||||
|
||||
# Function to safely get UCI value with default
|
||||
get_uci_value() {
|
||||
local value
|
||||
config_get value imei_profile "$1" "$2"
|
||||
echo "${value:-$2}"
|
||||
}
|
||||
|
||||
# Function to check if service is running
|
||||
check_service_status() {
|
||||
if [ -f "/var/run/imeiprofile.pid" ]; then
|
||||
pid=$(cat /var/run/imeiprofile.pid)
|
||||
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||
echo "running"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# Double check using process search
|
||||
if pgrep -f "/www/cgi-bin/services/imeiprofile.sh" >/dev/null; then
|
||||
echo "running"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "stopped"
|
||||
}
|
||||
|
||||
# Function to get last log entry
|
||||
get_last_log() {
|
||||
local LOG_FILE="/tmp/log/imeiprofile/imeiprofile.log"
|
||||
if [ -f "$LOG_FILE" ]; then
|
||||
tail -n 1 "$LOG_FILE"
|
||||
else
|
||||
echo "No log entries found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if init.d service is enabled
|
||||
check_service_enabled() {
|
||||
if [ -f "/etc/init.d/imeiprofile-service" ]; then
|
||||
if /etc/init.d/imeiprofile-service enabled; then
|
||||
echo "true"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
echo "false"
|
||||
}
|
||||
|
||||
# Load QuecManager configuration
|
||||
config_load quecmanager
|
||||
|
||||
# Check if IMEI Profile section exists
|
||||
if ! uci -q get quecmanager.imei_profile >/dev/null; then
|
||||
echo '{"status": "inactive", "message": "IMEI Profile service is not configured"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get enabled status from UCI
|
||||
enabled=$(get_uci_value "enabled" "0")
|
||||
|
||||
if [ "$enabled" != "1" ]; then
|
||||
echo '{"status": "inactive", "message": "IMEI Profile service is disabled"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if service script exists
|
||||
if [ ! -f "/www/cgi-bin/services/imeiprofile.sh" ]; then
|
||||
echo '{"status": "error", "message": "Service script is missing"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get service status information
|
||||
service_status=$(check_service_status)
|
||||
service_enabled=$(check_service_enabled)
|
||||
last_log=$(get_last_log)
|
||||
|
||||
# Fetch configuration values from UCI
|
||||
iccid_profile1=$(get_uci_value "iccid_profile1" "")
|
||||
imei_profile1=$(get_uci_value "imei_profile1" "")
|
||||
iccid_profile2=$(get_uci_value "iccid_profile2" "")
|
||||
imei_profile2=$(get_uci_value "imei_profile2" "")
|
||||
|
||||
# Function to check if profile data exists
|
||||
validate_profile_data() {
|
||||
local iccid="$1"
|
||||
local imei="$2"
|
||||
[ -n "$iccid" ] && [ -n "$imei" ]
|
||||
}
|
||||
|
||||
# Build JSON response
|
||||
cat <<EOF
|
||||
{
|
||||
"status": "active",
|
||||
"service": {
|
||||
"status": "${service_status}",
|
||||
"enabled": ${service_enabled},
|
||||
"script": "$([ -f "/www/cgi-bin/services/imeiprofile.sh" ] && echo "present" || echo "missing")",
|
||||
"initScript": "$([ -f "/etc/init.d/imeiprofile-service" ] && echo "present" || echo "missing")"
|
||||
},
|
||||
"profiles": {
|
||||
EOF
|
||||
|
||||
# Add Profile 1 if it exists
|
||||
if validate_profile_data "$iccid_profile1" "$imei_profile1"; then
|
||||
cat <<EOF
|
||||
"profile1": {
|
||||
"iccid": "${iccid_profile1}",
|
||||
"imei": "${imei_profile1}"
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Add Profile 2 if it exists
|
||||
if validate_profile_data "$iccid_profile2" "$imei_profile2"; then
|
||||
# Add comma if Profile 1 was added
|
||||
[ -n "$iccid_profile1" ] && echo ","
|
||||
cat <<EOF
|
||||
"profile2": {
|
||||
"iccid": "${iccid_profile2}",
|
||||
"imei": "${imei_profile2}"
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Close the profiles object and add last activity
|
||||
cat <<EOF
|
||||
},
|
||||
"lastActivity": "${last_log}"
|
||||
}
|
||||
EOF
|
||||
@@ -0,0 +1,291 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Read POST data
|
||||
read -r QUERY_STRING
|
||||
|
||||
# Function to urldecode
|
||||
urldecode() {
|
||||
local value="$1"
|
||||
value="${value//+/ }"
|
||||
value="${value//%/\\x}"
|
||||
printf '%b' "$value"
|
||||
}
|
||||
|
||||
# Extract values from POST data
|
||||
iccidProfile1=$(echo "$QUERY_STRING" | sed -n 's/.*iccidProfile1=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
imeiProfile1=$(echo "$QUERY_STRING" | sed -n 's/.*imeiProfile1=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
iccidProfile2=$(echo "$QUERY_STRING" | sed -n 's/.*iccidProfile2=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
imeiProfile2=$(echo "$QUERY_STRING" | sed -n 's/.*imeiProfile2=\([^&]*\).*/\1/p' | tr -d "'")
|
||||
|
||||
# URL decode the values
|
||||
iccidProfile1=$(urldecode "$iccidProfile1")
|
||||
imeiProfile1=$(urldecode "$imeiProfile1")
|
||||
iccidProfile2=$(urldecode "$iccidProfile2")
|
||||
imeiProfile2=$(urldecode "$imeiProfile2")
|
||||
|
||||
echo "Content-type: application/json"
|
||||
echo ""
|
||||
|
||||
# Validate required first profile
|
||||
if [ -z "$iccidProfile1" ] || [ -z "$imeiProfile1" ]; then
|
||||
echo '{"status": "error", "message": "Profile 1 is required"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local LOG_DIR="/tmp/log/imeiprofile"
|
||||
local LOG_FILE="${LOG_DIR}/imeiprofile.log"
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "${timestamp} - [${level}] ${message}" >> "$LOG_FILE"
|
||||
logger -t imeiprofile "${level}: ${message}"
|
||||
}
|
||||
|
||||
# Create required directories
|
||||
mkdir -p /www/cgi-bin/services
|
||||
|
||||
# Function to create service script
|
||||
create_service_script() {
|
||||
cat > /www/cgi-bin/services/imeiprofile.sh <<'EOL'
|
||||
#!/bin/sh
|
||||
|
||||
# Load UCI functions
|
||||
. /lib/functions.sh
|
||||
|
||||
# Define file paths
|
||||
QUEUE_FILE="/tmp/at_pipe.txt"
|
||||
LOG_DIR="/tmp/log/imeiprofile"
|
||||
LOG_FILE="${LOG_DIR}/imeiprofile.log"
|
||||
PID_FILE="/var/run/imeiprofile.pid"
|
||||
|
||||
mkdir -p "${LOG_DIR}"
|
||||
[ ! -f "${QUEUE_FILE}" ] && touch "${QUEUE_FILE}"
|
||||
|
||||
# Save PID
|
||||
echo $$ > "${PID_FILE}"
|
||||
|
||||
# Enhanced logging function
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "${timestamp} - [${level}] ${message}" >> "$LOG_FILE"
|
||||
logger -t imeiprofile "${level}: ${message}"
|
||||
}
|
||||
|
||||
# AT command handling with locking
|
||||
handle_lock() {
|
||||
local max_wait=30
|
||||
local wait_count=0
|
||||
|
||||
while [ -f "$QUEUE_FILE" ] && grep -q "AT_COMMAND" "$QUEUE_FILE" && [ $wait_count -lt $max_wait ]; do
|
||||
sleep 1
|
||||
wait_count=$((wait_count + 1))
|
||||
done
|
||||
|
||||
printf '{"command":"AT_COMMAND","pid":"%s","timestamp":"%s"}\n' "$$" "$(date '+%H:%M:%S')" >> "$QUEUE_FILE"
|
||||
}
|
||||
|
||||
# Execute AT command with retries
|
||||
execute_at_command() {
|
||||
local command="$1"
|
||||
local result=""
|
||||
local retry_count=0
|
||||
local max_retries=3
|
||||
|
||||
while [ $retry_count -lt $max_retries ]; do
|
||||
handle_lock
|
||||
result=$(sms_tool at "$command" -t 4 2>&1)
|
||||
local status=$?
|
||||
sed -i "/\"pid\":\"$$\"/d" "$QUEUE_FILE"
|
||||
|
||||
if [ $status -eq 0 ] && [ -n "$result" ]; then
|
||||
echo "$result"
|
||||
return 0
|
||||
fi
|
||||
|
||||
retry_count=$((retry_count + 1))
|
||||
[ $retry_count -lt $max_retries ] && sleep 2
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# Get current ICCID
|
||||
get_current_iccid() {
|
||||
local result=$(execute_at_command "AT+ICCID")
|
||||
if [ $? -eq 0 ] && echo "$result" | grep -q "+ICCID:"; then
|
||||
echo "$result" | grep "+ICCID:" | cut -d' ' -f2 | tr -d '[:space:]'
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Get current IMEI
|
||||
get_current_imei() {
|
||||
local result=$(execute_at_command "AT+CGSN")
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "$result" | grep -v "AT+CGSN" | grep -v "OK" | tr -d '\r\n[:space:]'
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Set IMEI
|
||||
set_imei() {
|
||||
local imei="$1"
|
||||
if execute_at_command "AT+EGMR=1,7,\"$imei\";+QPOWD=1"; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to safely get UCI value with default
|
||||
get_uci_value() {
|
||||
local value
|
||||
config_get value imei_profile "$1" "$2"
|
||||
echo "${value:-$2}"
|
||||
}
|
||||
|
||||
# Main service loop
|
||||
while true; do
|
||||
# Load current configuration
|
||||
config_load quecmanager
|
||||
|
||||
# Get Profile 1
|
||||
iccid_profile1=$(get_uci_value "iccid_profile1")
|
||||
imei_profile1=$(get_uci_value "imei_profile1")
|
||||
|
||||
# Get Profile 2
|
||||
iccid_profile2=$(get_uci_value "iccid_profile2")
|
||||
imei_profile2=$(get_uci_value "imei_profile2")
|
||||
|
||||
# Get current ICCID and IMEI
|
||||
current_iccid=$(get_current_iccid)
|
||||
current_imei=$(get_current_imei)
|
||||
|
||||
if [ $? -eq 0 ] && [ -n "$current_iccid" ] && [ -n "$current_imei" ]; then
|
||||
if [ "${current_iccid}" = "${iccid_profile1}" ]; then
|
||||
if [ "${current_imei}" != "${imei_profile1}" ]; then
|
||||
if set_imei "${imei_profile1}"; then
|
||||
log_message "INFO" "Successfully applied Profile 1 IMEI"
|
||||
else
|
||||
log_message "ERROR" "Failed to apply Profile 1 IMEI"
|
||||
fi
|
||||
fi
|
||||
elif [ -n "$iccid_profile2" ] && [ "${current_iccid}" = "${iccid_profile2}" ]; then
|
||||
if [ "${current_imei}" != "${imei_profile2}" ]; then
|
||||
if set_imei "${imei_profile2}"; then
|
||||
log_message "INFO" "Successfully applied Profile 2 IMEI"
|
||||
else
|
||||
log_message "ERROR" "Failed to apply Profile 2 IMEI"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_message "INFO" "No matching ICCID profile found"
|
||||
fi
|
||||
else
|
||||
log_message "ERROR" "Failed to get current ICCID or IMEI"
|
||||
fi
|
||||
|
||||
sleep 30
|
||||
done
|
||||
EOL
|
||||
|
||||
chmod 755 /www/cgi-bin/services/imeiprofile.sh
|
||||
}
|
||||
|
||||
# Function to create init.d script
|
||||
create_init_script() {
|
||||
cat > /etc/init.d/imeiprofile-service <<'EOL'
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
local enabled
|
||||
|
||||
# Check if service is enabled in UCI
|
||||
config_load quecmanager
|
||||
config_get enabled imei_profile enabled '0'
|
||||
|
||||
[ "$enabled" != "1" ] && return 0
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /www/cgi-bin/services/imeiprofile.sh
|
||||
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_set_param nice 19
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "quecmanager"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
EOL
|
||||
|
||||
chmod 755 /etc/init.d/imeiprofile-service
|
||||
}
|
||||
|
||||
# Initialize UCI configuration
|
||||
touch /etc/config/quecmanager
|
||||
|
||||
# Remove existing IMEI profile section if it exists
|
||||
uci -q delete quecmanager.imei_profile
|
||||
|
||||
# Create new IMEI profile section
|
||||
uci set quecmanager.imei_profile=service
|
||||
uci set quecmanager.imei_profile.enabled=1
|
||||
|
||||
# Set Profile 1 configuration
|
||||
uci set quecmanager.imei_profile.iccid_profile1="$iccidProfile1"
|
||||
uci set quecmanager.imei_profile.imei_profile1="$imeiProfile1"
|
||||
|
||||
# Set Profile 2 configuration if provided
|
||||
if [ -n "$iccidProfile2" ]; then
|
||||
uci set quecmanager.imei_profile.iccid_profile2="$iccidProfile2"
|
||||
uci set quecmanager.imei_profile.imei_profile2="$imeiProfile2"
|
||||
fi
|
||||
|
||||
# Commit UCI changes
|
||||
if ! uci commit quecmanager; then
|
||||
log_message "ERROR" "Failed to save UCI configuration"
|
||||
echo '{"status": "error", "message": "Failed to save UCI configuration"}'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_message "INFO" "UCI configuration saved successfully"
|
||||
|
||||
# Create service script if it doesn't exist
|
||||
if [ ! -f "/www/cgi-bin/services/imeiprofile.sh" ]; then
|
||||
create_service_script
|
||||
log_message "INFO" "Created service script"
|
||||
fi
|
||||
|
||||
# Create init.d script if it doesn't exist
|
||||
if [ ! -f "/etc/init.d/imeiprofile-service" ]; then
|
||||
create_init_script
|
||||
log_message "INFO" "Created init.d script"
|
||||
fi
|
||||
|
||||
# Enable and start the service
|
||||
/etc/init.d/imeiprofile-service enable
|
||||
if /etc/init.d/imeiprofile-service restart; then
|
||||
log_message "INFO" "Service started successfully"
|
||||
echo '{"status": "success", "message": "IMEI profiles saved and service started"}'
|
||||
else
|
||||
log_message "ERROR" "Failed to start service"
|
||||
echo '{"status": "error", "message": "Failed to start service"}'
|
||||
fi
|
||||
@@ -0,0 +1,262 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Configuration
|
||||
CONFIG_FILE="/etc/cell_lock_schedule.conf"
|
||||
STATUS_FILE="/tmp/cell_lock_status"
|
||||
CELL_LOCK_SCRIPT="/usr/bin/set_cell_lock.sh"
|
||||
QUEUE_FILE="/tmp/at_pipe.txt"
|
||||
LOG_FILE="/tmp/cell_lock.log"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "${timestamp} - [${level}] ${message}" >> "$LOG_FILE"
|
||||
logger -t cell_lock "${level}: ${message}"
|
||||
}
|
||||
|
||||
# Function to handle AT command queue
|
||||
handle_lock() {
|
||||
log_message "DEBUG" "Checking queue file status before lock"
|
||||
if [ ! -f "$QUEUE_FILE" ]; then
|
||||
log_message "DEBUG" "Queue file does not exist, creating it"
|
||||
touch "$QUEUE_FILE"
|
||||
fi
|
||||
|
||||
# Clean any stale entries
|
||||
if grep -q "\"command\":\"AT_COMMAND\"" "$QUEUE_FILE"; then
|
||||
local wait_count=0
|
||||
while [ $wait_count -lt 6 ]; do
|
||||
if ! grep -q "\"command\":\"AT_COMMAND\"" "$QUEUE_FILE"; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
wait_count=$((wait_count + 1))
|
||||
done
|
||||
[ $wait_count -eq 6 ] && sed -i "/\"command\":\"AT_COMMAND\"/d" "$QUEUE_FILE"
|
||||
fi
|
||||
|
||||
printf '{"command":"AT_COMMAND","pid":"%s","timestamp":"%s"}\n' \
|
||||
"$$" \
|
||||
"$(date '+%H:%M:%S')" >> "$QUEUE_FILE"
|
||||
}
|
||||
|
||||
# Function to execute AT command
|
||||
execute_at_command() {
|
||||
local command="$1"
|
||||
local result=""
|
||||
|
||||
log_message "DEBUG" "Executing AT command: ${command}"
|
||||
handle_lock
|
||||
|
||||
result=$(sms_tool at "$command" -t 4 2>&1)
|
||||
local status=$?
|
||||
|
||||
sed -i "/\"pid\":\"$$\"/d" "$QUEUE_FILE"
|
||||
|
||||
if [ $status -ne 0 ]; then
|
||||
log_message "ERROR" "Command failed with status $status: $command"
|
||||
log_message "ERROR" "Command output: $result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_message "DEBUG" "Command successful. Output: $result"
|
||||
echo "$result"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to create set_cell_lock.sh script
|
||||
create_cell_lock_script() {
|
||||
if [ ! -f "$CELL_LOCK_SCRIPT" ]; then
|
||||
cat >"$CELL_LOCK_SCRIPT" <<'EOL'
|
||||
#!/bin/sh
|
||||
|
||||
ACTION=$1
|
||||
LTE_PARAMS=$2
|
||||
NR5G_PARAMS=$3
|
||||
|
||||
QUEUE_FILE="/tmp/at_pipe.txt"
|
||||
LOG_FILE="/tmp/cell_lock.log"
|
||||
|
||||
# Import common functions
|
||||
. /etc/quecmanager/imei_profile/common_functions.sh || {
|
||||
echo "Failed to import common functions"
|
||||
exit 1
|
||||
}
|
||||
|
||||
case "$ACTION" in
|
||||
enable)
|
||||
# Enable LTE lock if parameters exist
|
||||
if [ -n "$LTE_PARAMS" ]; then
|
||||
execute_at_command "AT+QNWLOCK=\"common/4g\",$LTE_PARAMS"
|
||||
fi
|
||||
|
||||
# Enable NR5G lock if parameters exist
|
||||
if [ -n "$NR5G_PARAMS" ]; then
|
||||
execute_at_command "AT+QNWLOCK=\"common/5g\",$NR5G_PARAMS"
|
||||
fi
|
||||
;;
|
||||
|
||||
disable)
|
||||
# Disable LTE lock
|
||||
execute_at_command "AT+QNWLOCK=\"common/4g\",0"
|
||||
|
||||
# Disable NR5G lock
|
||||
execute_at_command "AT+QNWLOCK=\"common/5g\",0"
|
||||
;;
|
||||
|
||||
*)
|
||||
log_message "ERROR" "Invalid action: $ACTION"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Restart network registration to apply changes
|
||||
execute_at_command "AT+COPS=2"
|
||||
sleep 2
|
||||
execute_at_command "AT+COPS=0"
|
||||
exit 0
|
||||
EOL
|
||||
|
||||
chmod +x "$CELL_LOCK_SCRIPT"
|
||||
log_message "INFO" "Created cell lock script at $CELL_LOCK_SCRIPT"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to remove set_cell_lock.sh script
|
||||
remove_cell_lock_script() {
|
||||
if [ -f "$CELL_LOCK_SCRIPT" ]; then
|
||||
rm "$CELL_LOCK_SCRIPT"
|
||||
log_message "INFO" "Removed cell lock script"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to urldecode
|
||||
urldecode() {
|
||||
echo -e "$(echo "$1" | sed 's/+/ /g;s/%\([0-9A-F][0-9A-F]\)/\\x\1/g')"
|
||||
}
|
||||
|
||||
# Function to convert HH:MM to cron format
|
||||
convert_to_cron_time() {
|
||||
echo "$1" | awk -F: '{print $2, $1}'
|
||||
}
|
||||
|
||||
# Function to save configuration
|
||||
save_config() {
|
||||
echo "START_TIME=$1" >"$CONFIG_FILE"
|
||||
echo "END_TIME=$2" >>"$CONFIG_FILE"
|
||||
echo "ENABLED=1" >>"$CONFIG_FILE"
|
||||
log_message "INFO" "Saved configuration - Start: $1, End: $2"
|
||||
}
|
||||
|
||||
# Function to disable scheduling
|
||||
disable_scheduling() {
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
sed -i 's/ENABLED=1/ENABLED=0/' "$CONFIG_FILE"
|
||||
log_message "INFO" "Disabled scheduling"
|
||||
fi
|
||||
crontab -l | grep -v "set_cell_lock.sh" | crontab -
|
||||
remove_cell_lock_script
|
||||
}
|
||||
|
||||
# Function to get current status
|
||||
get_status() {
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
ENABLED=$(grep "ENABLED=" "$CONFIG_FILE" | cut -d'=' -f2)
|
||||
START_TIME=$(grep "START_TIME=" "$CONFIG_FILE" | cut -d'=' -f2)
|
||||
END_TIME=$(grep "END_TIME=" "$CONFIG_FILE" | cut -d'=' -f2)
|
||||
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"enabled\":$ENABLED,\"start_time\":\"$START_TIME\",\"end_time\":\"$END_TIME\"}"
|
||||
else
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"enabled\":0,\"start_time\":\"\",\"end_time\":\"\"}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle POST requests
|
||||
if [ "$REQUEST_METHOD" = "POST" ]; then
|
||||
read -r POST_DATA
|
||||
|
||||
if echo "$POST_DATA" | grep -q "disable=true"; then
|
||||
disable_scheduling
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"status\":\"success\",\"message\":\"Scheduling disabled\"}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
START_TIME=$(echo "$POST_DATA" | grep -o 'start_time=[^&]*' | cut -d'=' -f2)
|
||||
END_TIME=$(echo "$POST_DATA" | grep -o 'end_time=[^&]*' | cut -d'=' -f2)
|
||||
|
||||
START_TIME=$(urldecode "$START_TIME")
|
||||
END_TIME=$(urldecode "$END_TIME")
|
||||
|
||||
if [ -z "$START_TIME" ] || [ -z "$END_TIME" ]; then
|
||||
log_message "ERROR" "Missing start or end time"
|
||||
echo "Status: 400 Bad Request"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"error\":\"Missing start or end time\"}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
create_cell_lock_script
|
||||
|
||||
CRON_START=$(convert_to_cron_time "$START_TIME")
|
||||
CRON_END=$(convert_to_cron_time "$END_TIME")
|
||||
|
||||
save_config "$START_TIME" "$END_TIME"
|
||||
|
||||
# Check current cell lock status and get parameters
|
||||
LTE_STATUS=$(execute_at_command 'AT+QNWLOCK="common/4g"')
|
||||
NR5G_STATUS=$(execute_at_command 'AT+QNWLOCK="common/5g"')
|
||||
|
||||
LTE_PARAMS=$(echo "$LTE_STATUS" | grep -o '"common/4g",[^[:space:]]*' | cut -d',' -f2-)
|
||||
NR5G_PARAMS=$(echo "$NR5G_STATUS" | grep -o '"common/5g",[^[:space:]]*' | cut -d',' -f2-)
|
||||
|
||||
TEMP_CRON=$(mktemp)
|
||||
|
||||
crontab -l 2>/dev/null | grep -v "set_cell_lock.sh" >"$TEMP_CRON"
|
||||
|
||||
echo "$CRON_START * * * $CELL_LOCK_SCRIPT enable \"$LTE_PARAMS\" \"$NR5G_PARAMS\"" >>"$TEMP_CRON"
|
||||
echo "$CRON_END * * * $CELL_LOCK_SCRIPT disable" >>"$TEMP_CRON"
|
||||
|
||||
crontab "$TEMP_CRON"
|
||||
rm "$TEMP_CRON"
|
||||
|
||||
log_message "INFO" "Scheduling enabled with start time $START_TIME and end time $END_TIME"
|
||||
|
||||
echo "Status: 200 OK"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"status\":\"success\",\"message\":\"Scheduling enabled\"}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Parse query string for GET requests
|
||||
if [ "$REQUEST_METHOD" = "GET" ]; then
|
||||
QUERY_STRING=$(echo "$QUERY_STRING" | sed 's/&/\n/g')
|
||||
for param in $QUERY_STRING; do
|
||||
case "$param" in
|
||||
status=*)
|
||||
get_status
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
# If no valid request is made
|
||||
log_message "ERROR" "Invalid request received"
|
||||
echo "Status: 400 Bad Request"
|
||||
echo "Content-Type: application/json"
|
||||
echo ""
|
||||
echo "{\"error\":\"Invalid request\"}"
|
||||
exit 1
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Set content type
|
||||
printf "Content-Type: application/json\n\n"
|
||||
|
||||
# URL decode function
|
||||
urldecode() {
|
||||
echo "$*" | sed 's/+/ /g;s/%\([0-9A-F][0-9A-F]\)/\\\\x\1/g' | xargs -0 printf '%b'
|
||||
}
|
||||
|
||||
# Extract indexes from query string
|
||||
query=$(echo "$QUERY_STRING" | grep -o 'indexes=[^&]*' | cut -d= -f2)
|
||||
indexes=$(urldecode "$query")
|
||||
|
||||
# Function to output JSON response
|
||||
send_json() {
|
||||
printf '{"status":"%s","message":"%s"}\n' "$1" "$2"
|
||||
}
|
||||
|
||||
# Validate input
|
||||
if [ -z "$indexes" ]; then
|
||||
send_json "error" "No indexes provided"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Initialize counters
|
||||
success=0
|
||||
failure=0
|
||||
|
||||
# Process each index
|
||||
echo "$indexes" | tr ',' '\n' | while read -r index; do
|
||||
if [ -n "$index" ] && [ "$index" -eq "$index" ] 2>/dev/null; then
|
||||
if sms_tool delete "$index" 2>/dev/null; then
|
||||
success=$((success + 1))
|
||||
else
|
||||
failure=$((failure + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Send response
|
||||
if [ $success -gt 0 ]; then
|
||||
if [ $failure -eq 0 ]; then
|
||||
send_json "success" "Successfully deleted $success message(s)"
|
||||
else
|
||||
send_json "partial" "Deleted $success message(s), failed to delete $failure message(s)"
|
||||
fi
|
||||
else
|
||||
send_json "error" "Failed to delete messages"
|
||||
fi
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
printf "Content-type: application/json\r\n\r\n"
|
||||
|
||||
# Execute the command and return the JSON response
|
||||
if command -v sms_tool > /dev/null 2>&1; then
|
||||
sms_tool -j recv
|
||||
else
|
||||
printf '{"error": "sms_tool not found"}\n'
|
||||
fi
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "Content-Type: application/json"
|
||||
echo "Cache-Control: no-cache"
|
||||
echo ""
|
||||
|
||||
# Function to URL decode the string
|
||||
urldecode() {
|
||||
local url_encoded="${1//+/ }"
|
||||
printf '%b' "${url_encoded//%/\\x}"
|
||||
}
|
||||
|
||||
# Function to escape JSON string
|
||||
escape_json() {
|
||||
printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g; s/\r/\\r/g; s/\t/\\t/g'
|
||||
}
|
||||
|
||||
# Read POST data
|
||||
read -r QUERY_STRING
|
||||
|
||||
# Extract phone and message from POST data
|
||||
phone=$(echo "$QUERY_STRING" | grep -o 'phone=[^&]*' | cut -d= -f2)
|
||||
message=$(echo "$QUERY_STRING" | grep -o 'message=[^&]*' | cut -d= -f2)
|
||||
|
||||
# URL decode the message
|
||||
decoded_message=$(urldecode "$message")
|
||||
|
||||
# Validate inputs
|
||||
if [ -z "$phone" ] || [ -z "$message" ]; then
|
||||
echo '{"success":false,"error":"Phone number and message are required"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Validate phone number (only numbers allowed)
|
||||
if ! echo "$phone" | grep -q '^[0-9]\+$'; then
|
||||
echo '{"success":false,"error":"Invalid phone number format"}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Try to send SMS and capture output
|
||||
result=$(sms_tool send "$phone" "$decoded_message" 2>&1)
|
||||
escaped_result=$(escape_json "$result")
|
||||
|
||||
# Check if SMS was sent successfully by looking for "sms sent sucessfully"
|
||||
if echo "$result" | grep -q "sms sent sucessfully"; then
|
||||
# Extract the message ID if present
|
||||
message_id=$(echo "$result" | grep -o '[0-9]*$')
|
||||
echo "{\"success\":true,\"message\":\"SMS sent successfully\",\"messageId\":\"$message_id\",\"raw\":\"$escaped_result\"}"
|
||||
elif echo "$result" | grep -q "sms not sent, code 350"; then
|
||||
# Kill any hanging sms_tool process
|
||||
pkill -f "sms_tool send"
|
||||
echo '{"success":false,"error":"No prepaid credit available"}'
|
||||
else
|
||||
# Kill any hanging sms_tool process
|
||||
pkill -f "sms_tool send"
|
||||
echo "{\"success\":false,\"error\":\"Failed to send SMS\",\"raw\":\"$escaped_result\"}"
|
||||
fi
|
||||
Reference in New Issue
Block a user