Astranome

SmartWatchDog

Jun 24th, 2026
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 9.31 KB | Source Code | 0 0
  1. #!/bin/bash
  2. # Умный watchdog для PlutoSDR v5 (Полный исправленный вариант)
  3. # Включает: автокалибровку, периодическую проверку, восстановление после любых сбросов
  4.  
  5. LOGFILE="/var/log/pluto_smart_watchdog.log"
  6. TRX_LOG="/tmp/trx.log"
  7. BTS_LOG="/tmp/bts.log"
  8. CONFIG_DIR="/root/osmo-trx_soapy/Osmocom_configs/VOICE"
  9. TRX_DIR="/root/osmo-trx_soapy/Transceiver52M"
  10. SESSION="gsm_base"
  11.  
  12. # Калибровка PlutoSDR NANO
  13. PLUTO_IP="192.168.2.1"
  14. XO_VALUE=39999368  # ← Ваша уникальная калибровка!
  15.  
  16. # Интервалы
  17. CHECK_INTERVAL=120
  18. MAX_SOFT_RESTARTS=3
  19. MAX_USB_RESETS=2
  20. RESTART_DELAY=30
  21. STABILIZATION_TIME=180
  22.  
  23. # Счётчики
  24. SOFT_RESTART_COUNT=0
  25. USB_RESET_COUNT=0
  26. LAST_ERROR_TIME=0
  27. LAST_RESTART_TIME=0
  28.  
  29. log() {
  30.     echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> "$LOGFILE"
  31.     echo "$(date '+%Y-%m-%d %H:%M:%S'): $1"
  32. }
  33.  
  34. # ========== ФУНКЦИЯ КАЛИБРОВКИ (Улучшенная, с повторами) ==========
  35. calibrate_pluto() {
  36.     log "[CALIBRATE] Проверка и применение xo_correction = $XO_VALUE..."
  37.  
  38.     # Ждём доступности сети Pluto
  39.     local ping_ok=0
  40.     for i in {1..20}; do
  41.         if ping -c 1 -W 2 "$PLUTO_IP" > /dev/null 2>&1; then
  42.             ping_ok=1
  43.             break
  44.         fi
  45.         sleep 2
  46.     done
  47.  
  48.     if [ "$ping_ok" -eq 0 ]; then
  49.         log "[CALIBRATE] ❌ Pluto недоступен по сети"
  50.         return 1
  51.     fi
  52.  
  53.     # Даем время на инициализацию libiio после сброса
  54.     sleep 8
  55.  
  56.     # Применяем калибровку (до 3 попыток)
  57.     local attempt=0
  58.     while [ $attempt -lt 3 ]; do
  59.         attempt=$((attempt + 1))
  60.         log "[CALIBRATE] Попытка $attempt/3: запись xo_correction..."
  61.         iio_attr -u "ip:$PLUTO_IP" -d ad9361-phy xo_correction "$XO_VALUE" > /dev/null 2>&1
  62.         sleep 2
  63.  
  64.         # Читаем текущее значение
  65.         local raw_output
  66.         raw_output=$(iio_attr -u "ip:$PLUTO_IP" -d ad9361-phy xo_correction 2>/dev/null)
  67.         local current
  68.         current=$(echo "$raw_output" | grep -o '[0-9]\+' | head -1)
  69.  
  70.         if [ "$current" = "$XO_VALUE" ]; then
  71.             log "[CALIBRATE] ✅ Успешно: $current"
  72.             return 0
  73.         else
  74.             log "[CALIBRATE] ⚠️ Не совпало (ожид.: $XO_VALUE, факт.: $current). Повтор..."
  75.         fi
  76.     done
  77.  
  78.     log "[CALIBRATE]  Не удалось применить калибровку после 3 попыток!"
  79.     return 1
  80. }
  81. # ========================================================
  82.  
  83. # ========== ФУНКЦИЯ ПЕРИОДИЧЕСКОЙ ПРОВЕРКИ (НОВАЯ) ==========
  84. # Вызывается каждые 2 минуты. Если калибровка слетела (например, после кнопки RESET на Pluto),
  85. # скрипт обнаружит это и применит заново БЕЗ перезапуска процессов.
  86. check_calibration() {
  87.     local raw_output
  88.     raw_output=$(iio_attr -u "ip:$PLUTO_IP" -d ad9361-phy xo_correction 2>/dev/null)
  89.     local current
  90.     current=$(echo "$raw_output" | grep -o '[0-9]\+' | head -1)
  91.  
  92.     if [ -z "$current" ]; then
  93.         log "[CHECK] ⚠️ Не удалось прочитать xo_correction, принудительно применяем..."
  94.         calibrate_pluto
  95.         return
  96.     fi
  97.  
  98.     if [ "$current" != "$XO_VALUE" ]; then
  99.         log "[CHECK] ⚠️ Калибровка слетела! Было: $XO_VALUE, стало: $current. Исправляю..."
  100.         calibrate_pluto
  101.     fi
  102. }
  103. # ========================================================
  104.  
  105. check_trx_running() {
  106.     if ! pgrep -f "osmo-trx-soapy" > /dev/null; then return 1; fi
  107.     local state
  108.     state=$(ps -p "$(pgrep -f 'osmo-trx-soapy' | head -1)" -o state= 2>/dev/null)
  109.     [ "$state" = "Z" ] && return 1
  110.     return 0
  111. }
  112.  
  113. check_bts_running() {
  114.     if ! pgrep -f "osmo-bts-trx" > /dev/null; then return 1; fi
  115.     local state
  116.     state=$(ps -p "$(pgrep -f 'osmo-bts-trx' | head -1)" -o state= 2>/dev/null)
  117.     [ "$state" = "Z" ] && return 1
  118.     return 0
  119. }
  120.  
  121. check_pluto_usb() {
  122.     lsusb | grep -q "0456:b673" && return 0 || return 1
  123. }
  124.  
  125. check_for_errors() {
  126.     if [ -f "$TRX_LOG" ] && tail -20 "$TRX_LOG" | grep -qE "FATAL|Device receive timed out"; then return 0; fi
  127.     if [ -f "$BTS_LOG" ] && tail -20 "$BTS_LOG" | grep -qE "TRX closed"; then return 0; fi
  128.     return 1
  129. }
  130.  
  131. soft_restart() {
  132.     log "[RESTART] Мягкий перезапуск процессов..."
  133.     pkill -9 -f "osmo-trx-soapy" 2>/dev/null
  134.     pkill -9 -f "osmo-bts-trx" 2>/dev/null
  135.     tmux kill-session -t "$SESSION" 2>/dev/null
  136.     sleep 3
  137.  
  138.     > "$TRX_LOG" 2>/dev/null
  139.     > "$BTS_LOG" 2>/dev/null
  140.  
  141.     # === ВАЖНО: калибруем ПЕРЕД запуском процессов ===
  142.     calibrate_pluto
  143.  
  144.     tmux new-session -d -s "$SESSION" -n 'BASE'
  145.     tmux split-window -v -t "$SESSION:0"
  146.     tmux select-layout -t "$SESSION:0" even-vertical
  147.  
  148.     tmux send-keys -t "$SESSION:0.0" "cd $CONFIG_DIR && osmo-bts-trx -c osmo-bts-trx.cfg 2>&1 | tee -a $BTS_LOG" Enter
  149.     tmux send-keys -t "$SESSION:0.1" "cd $TRX_DIR && ./osmo-trx-soapy -C test1.cfg 2>&1 | tee -a $TRX_LOG" Enter
  150.  
  151.     log "[RESTART] Ожидание запуска ($RESTART_DELAY сек)..."
  152.     sleep $RESTART_DELAY
  153.  
  154.     if check_trx_running && check_bts_running; then
  155.         log "[RESTART] ✅ Успешно запущено"
  156.         LAST_RESTART_TIME=$(date +%s)
  157.         log "[DISPLAY] Перезапуск отображения на tty1..."
  158.         sudo systemctl restart gsm-display.service
  159.         sleep 2
  160.         return 0
  161.     else
  162.         log "[RESTART] ❌ Ошибка запуска"
  163.         return 1
  164.     fi
  165. }
  166.  
  167. usb_reset() {
  168.     log "[USB] Сброс USB устройства..."
  169.     local PLUTO_PATH
  170.     PLUTO_PATH=$(ls -l /sys/bus/usb/devices/*/ | grep "0456:b673" 2>/dev/null | head -1 | cut -d'/' -f6)
  171.  
  172.     if [ -z "$PLUTO_PATH" ]; then
  173.         log "[USB] ❌ Устройство не найдено"
  174.         return 1
  175.     fi
  176.  
  177.     echo -n "$PLUTO_PATH" | sudo tee /sys/bus/usb/drivers/usb/unbind > /dev/null 2>&1
  178.     sleep 3
  179.     echo -n "$PLUTO_PATH" | sudo tee /sys/bus/usb/drivers/usb/bind > /dev/null 2>&1
  180.     sleep 5
  181.  
  182.     if lsusb | grep -q "0456:b673"; then
  183.         log "[USB] ✅ Сброс выполнен"
  184.         calibrate_pluto  # Калибруем после аппаратного сброса USB
  185.         return $?
  186.     else
  187.         log "[USB] ❌ Сброс не удался"
  188.         return 1
  189.     fi
  190. }
  191.  
  192. full_reboot() {
  193.     log "[REBOOT]  Полная перезагрузка системы!"
  194.     sleep 3
  195.     sudo reboot
  196. }
  197.  
  198. handle_error() {
  199.     local CURRENT_TIME
  200.     CURRENT_TIME=$(date +%s)
  201.  
  202.     if [ $((CURRENT_TIME - LAST_RESTART_TIME)) -lt $STABILIZATION_TIME ]; then
  203.         log "[SKIP] Недавно был перезапуск, пропускаю проверку"
  204.         return
  205.     fi
  206.  
  207.     if [ $((CURRENT_TIME - LAST_ERROR_TIME)) -gt 3600 ]; then
  208.         SOFT_RESTART_COUNT=0
  209.         USB_RESET_COUNT=0
  210.     fi
  211.  
  212.     LAST_ERROR_TIME=$CURRENT_TIME
  213.  
  214.     if [ $SOFT_RESTART_COUNT -lt $MAX_SOFT_RESTARTS ]; then
  215.         SOFT_RESTART_COUNT=$((SOFT_RESTART_COUNT + 1))
  216.         soft_restart
  217.     elif [ $USB_RESET_COUNT -lt $MAX_USB_RESETS ]; then
  218.         USB_RESET_COUNT=$((USB_RESET_COUNT + 1))
  219.         if usb_reset; then
  220.             soft_restart
  221.         else
  222.             full_reboot
  223.         fi
  224.     else
  225.         log "[CRITICAL] Исчерпаны все попытки восстановления"
  226.         full_reboot
  227.     fi
  228. }
  229.  
  230. # ========== ГЛАВНЫЙ ЦИКЛ ==========
  231. log "========================================="
  232. log "Watchdog PlutoSDR v5 запущен"
  233. log "Интервал проверки: ${CHECK_INTERVAL}с"
  234. log "Целевая калибровка: $XO_VALUE"
  235. log "========================================="
  236.  
  237. # Первичная калибровка при старте скрипта
  238. calibrate_pluto
  239.  
  240. while true; do
  241.     # 1. Проверка физического подключения
  242.     if ! check_pluto_usb; then
  243.         log "[ERROR] PlutoSDR не найден в USB"
  244.         handle_error
  245.         sleep $CHECK_INTERVAL
  246.         continue
  247.     fi
  248.  
  249.     # 2. Проверка запущенных процессов
  250.     if ! check_trx_running || ! check_bts_running; then
  251.         log "[ERROR] Процессы osmo-trx/bts не работают"
  252.         handle_error
  253.         sleep $CHECK_INTERVAL
  254.         continue
  255.     fi
  256.  
  257.     # 3. === НОВАЯ ФУНКЦИЯ: Периодическая проверка калибровки ===
  258.     # Именно она спасает ситуацию, когда вы нажимаете RESET на Pluto,
  259.     # но USB не отваливается и процессы продолжают работать.
  260.     check_calibration
  261.  
  262.     # 4. Проверка логов на критические ошибки
  263.     if check_for_errors; then
  264.         log "[ERROR] Критические ошибки в логах"
  265.         handle_error
  266.         sleep $CHECK_INTERVAL
  267.         continue
  268.     fi
  269.  
  270.     sleep $CHECK_INTERVAL
  271. done
  272.  
Advertisement
Add Comment
Please, Sign In to add comment