Как вызвать свой скрипт в Asterisk после завершения вызова?

Я пытаюсь запустить tcpdump в конфигурационном файле <b>extensions_custom.conf</b>. Вот часть конфигурации: <pre><code>[from-internal-custom]
exten =&gt; _X.,1,AGI(tcpdump_ata_fxo.sh,start,${UNIQUEID})</code></pre> 
tcpdump успешно запускается, но мне нужно знать, как его остановить. 

При завершении вызова я искал триггеры в логах и попытался использовать следующую команду: 
<blockquote>AGI(tcpdump_ata_fxo.sh,<b>stop</b>,${UNIQUEID})</blockquote> 

В логах, где зафиксированы разговоры и нажатие кнопки завершения вызова, отсутствуют указания на остановку tcpdump. 

P.S. У устройства HT813 проблемы с качеством работы, и я хочу записать звонки по аналоговой линии (в процессе разговора). Искажения в передаче связи также беспокоят, поэтому я открыл тикет в службе поддержки Grandstream, и они просят предоставить логи и пакеты. Проблема непостоянная, и я уже настроил syslog сервер. Теперь мне нужно настроить tcpdump для захвата только звонков по транкам.
  • 3 декабря 2024 г. 21:33
Ответы на вопрос 2
Для того чтобы остановить выполнение `tcpdump` после завершения вызова в Asterisk, вы можете использовать два подхода.

### 1. Использование `AGI` и `Sub-context`

Вы уже запустили `tcpdump` через `AGI`, но вам нужно будет как-то определить момент окончания вызова и выполнить команду остановки. Один из способов — создать отдель контекст для завершения вызова. Вы можете сделать что-то подобное:

```ini
[from-internal-custom]
exten => _X.,1,AGI(tcpdump_ata_fxo.sh,start,${UNIQUEID})
exten => _X.,n,Wait(1) ; Небольшая задержка для стабильности
exten => _X.,n,Hangup()
exten => _X.,n,AGI(tcpdump_ata_fxo.sh,stop,${UNIQUEID})

; Контекст, куда попадёт вызов после завершения
exten => h,1,AGI(tcpdump_ata_fxo.sh,stop,${UNIQUEID})
```

В данном примере мы запускаем `tcpdump` при входящем звонке и останавливаем его при завершении вызова с помощью обработчика `h`, который срабатывает при завершении вызова.

### 2. Использование функции `h`

Дополнительно, вы можете использовать специальный контекст для завершения вызова:

```ini
[from-internal-custom]
exten => _X.,1,AGI(tcpdump_ata_fxo.sh,start,${UNIQUEID})
exten => _X.,n,Hangup()
exten => _X.,n,AGI(tcpdump_ata_fxo.sh,stop,${UNIQUEID})

; Запуск AGI для остановки после Hangup
exten => h,1,AGI(tcpdump_ata_fxo.sh,stop,${UNIQUEID})
```

### Пример скрипта tcpdump_ata_fxo.sh

Ваш скрипт `tcpdump_ata_fxo.sh` должен корректно обрабатывать команды `start` и `stop`. Пример:

```bash
#!/bin/bash

# Непосредственно путь к файлу для захвата.
DUMP_DIR="/tmp/tcpdump"

case "$1" in
    start)
        mkdir -p $DUMP_DIR
        tcpdump -i any -w "${DUMP_DIR}/call_${2}.pcap" &
        echo $! > "${DUMP_DIR}/tcpdump_pid_${2}.pid"
        ;;
    stop)
        if [ -f "${DUMP_DIR}/tcpdump_pid_${2}.pid" ]; then
            kill $(cat "${DUMP_DIR}/tcpdump_pid_${2}.pid")
            rm "${DUMP_DIR}/tcpdump_pid_${2}.pid"
        fi
        ;;
esac
```

### Заключение

Таким образом, вы сможете запустить `tcpdump` в момент начала вызова и корректно остановить его при завершении. При этом жильцы в вашем скрипте корректно обрабатываются через `AGI`. Не забудьте также проверить разрешения на создание/удаление файлов в целевой директории.
А зачем так усложнять себе жизнь? У tcpdump есть фильтр, в нём можно настроить адрес и порт, которые будут записываться. Просто запустите его в отдельном терминале через screen и получите дамп всего обмена с вашим шлюзом. 
А может вам вообще лучше подойдёт sngrep.
Ну или смотрите в сторону опций F и g у Dial.
Похожие вопросы