#!/usr/bin/env bash
# Съём трафика радио openHPSDR для разбора всплесков на передаче.
#
#   sudo test/hpsdr/capture.sh [-i bridge0] [-h 172.16.2.200] [-d /tmp/hpsdrcap]
#
# Пишет кольцевой буфер pcap (по умолчанию 24 x 150 МБ ~= 3.6 ГБ, это ~10-15 мин
# полного дуплекса) плюс лог счётчиков UDP-потерь ядра раз в секунду.
# Услышал/увидел всплеск — ЗАСЕКИ ВРЕМЯ и жми Ctrl-C: последние файлы кольца
# и есть нужный кусок.

set -euo pipefail

IFACE=bridge0
RADIO=172.16.2.200
OUTDIR=/tmp/hpsdrcap
FILES=24
SIZE=150

while getopts "i:h:d:n:s:" opt; do
  case "$opt" in
    i) IFACE=$OPTARG ;;
    h) RADIO=$OPTARG ;;
    d) OUTDIR=$OPTARG ;;
    n) FILES=$OPTARG ;;
    s) SIZE=$OPTARG ;;
    *) echo "usage: $0 [-i iface] [-h radio_ip] [-d outdir] [-n ring_files] [-s mb_per_file]" >&2; exit 2 ;;
  esac
done

if [ "$(id -u)" != 0 ]; then
  echo "нужен root (tcpdump): sudo $0 ..." >&2
  exit 1
fi

mkdir -p "$OUTDIR"
STAMP=$(date +%Y%m%d-%H%M%S)
echo "iface=$IFACE radio=$RADIO out=$OUTDIR/hpsdr-$STAMP-NNN.pcap ring=${FILES}x${SIZE}MB"
echo "старт: $(date -Ins)"

# Счётчики потерь ядра. Если растут — пакеты терялись НЕ на проводе, а в сокете
# приложения (мал rcvbuf / поток приёма не успевает), и в pcap всё будет чисто.
# drops=N в skmem — счётчик отброшенных ядром датаграмм этого сокета.
(
  while :; do
    printf '%s' "$(date +%s.%N)"
    awk '/^Udp:/{getline; printf " InErrors=%s RcvbufErrors=%s", $4, $6; exit}' /proc/net/snmp
    ss -uanm 2>/dev/null | awk '
      /^(UNCONN|ESTAB)/ { port=$4; rq=$2; next }
      /skmem:/ {
        rb=0; d=0;
        if (match($0, /rb[0-9]+/))  rb = substr($0, RSTART+2, RLENGTH-2);
        if (match($0, /,d[0-9]+\)/)) d  = substr($0, RSTART+2, RLENGTH-3);
        if (rb+0 > 1000000) printf " sock=%s rq=%s drops=%s", port, rq, d;
      }'
    echo
    sleep 1
  done
) > "$OUTDIR/hpsdr-$STAMP.drops" &
DROPPID=$!
trap 'kill $DROPPID 2>/dev/null || true' EXIT

# Без exec: exec заменил бы процесс оболочки и trap EXIT не сработал бы,
# оставив сборщик .drops сиротой навсегда.
tcpdump -i "$IFACE" -s 0 -B 65536 -n --time-stamp-precision=nano \
     -W "$FILES" -C "$SIZE" -w "$OUTDIR/hpsdr-$STAMP.pcap" \
     "udp and host $RADIO"
