25.04.2024

Fail2ban + PSD

 Router OS 6.4

PSD

/ip firewall filter 


add action=add-src-to-address-list address-list=DROP_BRUTFORCE address-list-timeout=1w3d chain=input comment="Port Scan" connection-state=invalid,new in-interface-list=WAN log=yes log-prefix=PSD_ psd=21,3s,3,1
 

Fail2ban for SSH

/ip firewall filter

add action=add-src-to-address-list address-list=DROP_BRUTFORCE address-list-timeout=1w3d chain=input connection-state=new dst-port=22 protocol=tcp src-address-list=ssh_stage3
add action=add-src-to-address-list address-list=ssh_stage3 address-list-timeout=1m chain=input connection-state=new dst-port=22 protocol=tcp src-address-list=ssh_stage2
add action=add-src-to-address-list address-list=ssh_stage2 address-list-timeout=1m chain=input connection-state=new dst-port=22 protocol=tcp src-address-list=ssh_stage1
add action=add-src-to-address-list address-list=ssh_stage1 address-list-timeout=1m chain=input connection-state=new dst-port=22 protocol=tcp
 

Fail2Ban for Winbox

/ip firewall filter

add action=jump chain=output comment="F2B Winbox: Jump to Fail2Ban-Destination-IP chain" content="invalid user name or password" jump-target=Fail2Ban-Destination-IP protocol=tcp src-port=8291
add action=add-dst-to-address-list address-list=DROP_BRUTFORCE address-list-timeout=1w3d chain=Fail2Ban-Destination-IP comment="3 Attempt --> BlackList" dst-address-list=LoginFailure02
add action=add-dst-to-address-list address-list=LoginFailure02 address-list-timeout=2m chain=Fail2Ban-Destination-IP comment="2 Attempt --> LoginFailure02" dst-address-list=LoginFailure01
add action=add-dst-to-address-list address-list=LoginFailure01 address-list-timeout=1m chain=Fail2Ban-Destination-IP comment="1 Attempt --> LoginFailure01"

28.08.2017

Sox

sox welcome.wav -r 8000 -b 16 -c 1 -t wav Welcome.wav

24.11.2016

Tcpdump

tcpdump -i eth0 -n -s 0 udp port 5060 or tcp port 5060 or udp portrange 10000-20000 -vvv -w /tmp/capturefilename

ngrep -q -d any -p -W byline '' 'port 5060'
Взято здесь 

17.10.2016

Backup Stage4 Gentoo

Самым простым способом сохранить систему целиком, является архивирование корневого каталога, в gentoo терминологии Stage 4.

Монтируем раздел с системой

mount /dev/sda1 /mnt/linux

Переходим к подмонтированному каталогу
cd /mnt/linux/

Архивируем корень
tar cjpvf /path/to/save/at/stage4.tar.bz2 ./

c — создание архива
j — использование bzip2 алгоритма сжатия
p — сохранять атрибуты файлов(НЕ УДАЛЯТЬ!!)
v — во время выполнения записывать в консоли текущий архивируемый файл
f — выводить в файл (иначе — в стандартный вывод)

Подготовьте раздел, куда будет установлена система.
Монтируем раздел.
mount /dev/sda1 /mnt/linux

Переходим к подмонтированному каталогу
cd /mnt/linux/

Разархивируем
tar -xvjpf stage4.tar.bz2

Смените корень и войдите в систему
chroot /mnt/linux

Установите загрузчик

19.09.2016

Чтоб не забыть.

dd

Программа dd ( disk dump ), используется для копирования ( конвертирования ) дисков, разделов, и прочих операций копирования. Типичный пример:
# dd if= of= bs= conv=
Важные опции для conv:
  • notrunc не обрезать нули в файле на выходе, записывая их как нули
  • noerror продолжать после ошибок чтения
  • sync дополнять каждый входящий блок нулями до размера ibs-size

Размер входных данных по-умолчанию 512 байт (1 блок). Увеличение размера блока ускоряет процесс копирования, но требует больше памяти.

Резервное копирование и восстановление

# dd if=/dev/hda of=/dev/hdc bs=16065b                # Копировать с диска на диск с таким-же размером
# dd if=/dev/sda7 of=/home/root.img bs=4096 conv=notrunc,noerror # Резервное копирование в файл образа
# dd if=/home/root.img of=/dev/sda7 bs=4096 conv=notrunc,noerror # Восстановление из файла образа
# dd bs=1M if=/dev/ad4s3e | gzip -c > ad4s3e.gz                  # Сделать резервную копию и заархивировать в Zip
# gunzip -dc ad4s3e.gz | dd of=/dev/ad0s3e bs=1M                 # Восстановить из архива
# dd bs=1M if=/dev/ad4s3e | gzip | ssh eedcoba@fry 'dd of=ad4s3e.gz' # Что и выше, удаленно
# gunzip -dc ad4s3e.gz | ssh eedcoba@host 'dd of=/dev/ad0s3e bs=1M'
# dd if=/dev/ad0 of=/dev/ad2 skip=1 seek=1 bs=4k conv=noerror    # Пропустить MBR ( Master Boot Record ) 
# Необходимо если диск назначения (ad2) меньше.

Лечение

Программа dd считывает раздел поблочно, если на диске предположительно есть проблемы, нужно использовать опцию conv=sync,noerror, при этом dd будет пропускать битые блоки и записывать нули на диск назначения. Поэтому важно, установить размер блока, равным, или меньшим, чем размер блока на диске. Вполне подходящим будет размер блока в 1 килобайт, установить размер на входе и выходе можно опцией bs=1k. Если на диске имеются сбойные сектора, но основные данные нужно сохранить с данного раздела, можно создать файл образа, смонтировать образ и копировать данные на новый диск. С установленной опцией noerror, dd пропустит поврежденные блоки, записав на их место нули, при этом, потеряны будут, только данные, содержавшиеся в сбойных секторах диска.
# dd if=/dev/hda of=/dev/null bs=1m                   # Проверить на наличие бэд блоков
# dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc | gzip | ssh \ # Отправить на удаленный хост
root@fry 'dd of=hda1.gz bs=1k'
# dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc of=hda1.img    # Сохранить в образ
# mount -o loop /hda1.img /mnt                        # Создание и монтирование образа
# rsync -ax /mnt/ /newdisk/                           # Копировать на новый диск
# dd if=/dev/hda of=/dev/hda                          # Обновить 
# Обновление диска, безопасная операция, но диск при этом должен быть размонтирован.

Удаление данных

# dd if=/dev/zero of=/dev/hdc                         # Удалить все данные с диска ( забивает диск нулями )
# dd if=/dev/urandom of=/dev/hdc                      # Удалить все данные с диска ( более предпочтительный вариант )
# kill -USR1 PID                                      # Посмотреть текущее состояние dd (Linux)
# kill -INFO PID                                      # Посмотреть текущее состояние dd (FreeBSD)

Трюки с MBR ( master boot record )

MBR содержит код загрузчика и таблицу разделов. Первый 466 байт отводятся под загрузчик, 466-512 под таблицу размещения разделов.
# dd if=/dev/sda of=/mbr_sda.bak bs=512 count=1       # Сделать резервную копию MBR
# dd if=/dev/zero of=/dev/sda bs=512 count=1          # Удалить MBR и таблицу размещения разделов
# dd if=/mbr_sda.bak of=/dev/sda bs=512 count=1       # Восстановить MBR целиком
# dd if=/mbr_sda.bak of=/dev/sda bs=446 count=1       # Восстановить только загрузчик
# dd if=/mbr_sda.bak of=/dev/sda bs=1 count=64 skip=446 seek=446 # Восстановить таблицу размещения разделов

Оригинал

05.01.2016

ACL+Realtime

Создаем таблицу:
CREATE TABLE `acltable` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(80) NOT NULL,
  `rule_order` int(11) NOT NULL,
  `sense` enum('permit','deny') NOT NULL DEFAULT 'deny',
  `rule` varchar(95) NOT NULL,
  PRIMARY KEY (`id`,`name`,`rule_order`,`sense`,`rule`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
В extconfig.conf говорим acls => mysql,asterisk,acltable

В данную таблицу вписываем данные:
name - имя ACL
rule_order - порядковый номер правила
sense - действие, возможно одно из 2-х: permit/deny
rule - IP/netmask 

Пример:
INSERT INTO `asterisk`.`acltable` (`name`, `rule_order`, `sense`, `rule`) VALUES ('lan', '1', 'permit', '10.0.10.0/24');
 
В таблице sippeers добавляем поле acl и добавляем имя ACL в это поле для нужного пира/транка.
  
При выполнении команды в CLI:  acl show  будет пустота.
При выполнении sip reload  применит нужный ACL.

Для обновления ACL кроме добавления записи в таблицу надо сделать module reload acl
При этом будет ошибка:
Named ACL 'lan' is already included in the ast_acl container.
chan_sip.c:31061 build_peer: Bad ACL entry in configuration line 11 : lan

Несмотря на ошибку ALC применяется, как пофиксить ошибку пока не разобрался.

Update 3.01.2016: Описание и патчи:
https://issues.asterisk.org/jira/browse/ASTERISK-24874
https://issues.asterisk.org/jira/browse/ASTERISK-24969

Realtime + register(row:callbackextension)+sip reload = Unregistered

Имеем проблему: если используем поле callbackextension в таблице Mysql и кол-во регистрации более 3-х, на меньшем не проявлялась, то при sip reload можем поиметь все регистрации со статусом Unregistered, помогает только рестарт * либо выгрузка/загрузка chan_sip.

Порывшись на просторах нашел вот это: https://issues.asterisk.org/jira/browse/ASTERISK-23789
на момент публикации еще открытый. Патч помогает, насколько он правильный судить не могу.

--- asterisk-12.2.0/channels/chan_sip.c 2014-04-21 17:02:00.000000000 -0400
+++ asterisk-12.2.0-modified/channels/chan_sip.c        2014-05-24 20:44:28.559519094 -0400
@@ -6566,8 +6566,12 @@
        AST_SCHED_DEL(sched, reg->expire);
        AST_SCHED_DEL(sched, reg->timeout);

+       if ((reg->;registryadded))
+       {
+               ast_atomic_fetchadd_int(&regobjs, -1);
+       }
+
        ast_string_field_free_memory(reg);
-       ast_atomic_fetchadd_int(&regobjs, -1);
        ast_free(reg);
 }

@@ -9556,6 +9560,7 @@
                registry_unref(tmp, "throw away found registry");
        } else {
                ast_atomic_fetchadd_int(&regobjs, 1);
+               reg->;registryadded = 1;
                ASTOBJ_CONTAINER_LINK(&regl, reg);
        }

--- asterisk-12.2.0/channels/sip/include/sip.h  2014-04-21 17:02:00.000000000 -0400
+++ asterisk-12.2.0-modified/channels/sip/include/sip.h 2014-05-24 20:37:42.557555124 -0400
@@ -1414,6 +1414,7 @@
        struct ast_sockaddr us;  /*!< Who the server thinks we are */
        int noncecount;         /*!< Nonce-count */
        char lastmsg[256];      /*!< Last Message sent/received */
+       unsigned short registryadded:1; /*!< If this registry object is already added to registry list */

 };

 struct tcptls_packet {
Update 10.01.2016
Порывшись еще найдено еще вот это: https://issues.asterisk.org/jira/browse/ASTERISK-23542
на момент публикации еще открытый.

--- channels/chan_sip.c    (revision 420532)
+++ channels/chan_sip.c    (working copy)
@@ -9218,11 +9218,12 @@
         reg->refresh = reg->expiry = reg->configured_expiry = default_expiry;
     }

+    ast_atomic_fetchadd_int(&regobjs, 1);
+
     /* Add the new registry entry to the list, but only if it isn't already there */
     if ((tmp = ASTOBJ_CONTAINER_FIND(&regl, reg->name))) {
         registry_unref(tmp, "throw away found registry");
     } else {
-        ast_atomic_fetchadd_int(&regobjs, 1);
         ASTOBJ_CONTAINER_LINK(&regl, reg);
     }


16.12.2015

Таблица CDR

Таблица CDR 
CREATE TABLE `cdr` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `calldate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `clid` VARCHAR(80) NOT NULL DEFAULT '',
  `src` VARCHAR(80) NOT NULL DEFAULT '',
  `dst` VARCHAR(80) NOT NULL DEFAULT '',
  `dcontext` VARCHAR(80) NOT NULL DEFAULT '',
  `channel` VARCHAR(80) NOT NULL DEFAULT '',
  `dstchannel` VARCHAR(80) NOT NULL DEFAULT '',
  `lastapp` VARCHAR(80) NOT NULL DEFAULT '',
  `lastdata` VARCHAR(80) NOT NULL DEFAULT '',
  `duration` INT(11) NOT NULL DEFAULT '0',
  `billsec` INT(11) NOT NULL DEFAULT '0',
  `disposition` VARCHAR(45) NOT NULL DEFAULT '',
  `amaflags` INT(11) NOT NULL DEFAULT '0',
  `accountcode` VARCHAR(20) NOT NULL DEFAULT '',
  `uniqueid` VARCHAR(32) NOT NULL DEFAULT '',
  `peeraccount` VARCHAR(20) NOT NULL DEFAULT '',
  `linkedid` VARCHAR(32) NOT NULL DEFAULT '',
  `sequence` INT(11) NOT NULL DEFAULT '0',
  `userfield` VARCHAR(255) NOT NULL DEFAULT '',
  `data` BLOB,
  `way` TINYINT(4) NOT NULL DEFAULT '0',
  `phn` INT(11) DEFAULT NULL,
  `active` TINYINT(4) NOT NULL DEFAULT '0',
  `tmp_val` VARCHAR(255) DEFAULT NULL,
  `rec_path` VARCHAR(255) DEFAULT NULL,
  `start` VARCHAR(255) DEFAULT NULL,
  `end` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `calldate` (`calldate`),
  KEY `accountcode` (`accountcode`),
  KEY `uniqueid` (`uniqueid`),
  KEY `dst` (`dst`),
  KEY `src` (`src`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

23.11.2015

insecure

Если у одного провайдера берем несколько транков то: 
Если в настройках транка стоит insecure=invite,port то все сыпется в первый в списке транк с этим ip. Если настроен Realtime то сначала ищем в базе а потом в файле.

Так как:
port: игнорировать номер порта, с которого пришла аутентификация
invite: не требовать начальное сообщение INVITE для аутентификации
port,invite: не требовать начальное сообщение INVITE для аутентификации и игнорировать порт, с которого пришел запрос

При установке  insecure=invite,port  - DID разгребаем в диалплане.

16.11.2015

Extracting Configuration with spacfg.xml from Linksys

Понадобилось сохранить конфиги:

http://<IP_address_of_phone>/spacfg.xml  - 8000
http://<IP_address_of_phone>/admin/spacfg.xml -303
http://<IP_address_of_phone>/admin/config.xml - 2102/3102(ver 5.2.13)

29.10.2015

Debug

Litnimax еще в 2009 году предложил:

И снова ты говоришь о pbx_config. Это там нужна отладка, в CLI. При выносе всей логики в mod_lua, ты волен сам делать такой debug, какой тебе хочется:
logger = logging.file("/tmp/test-%s.log", "%Y-%m-%d") logging.file("/tmp/test-%s.log", "%Y-%m-%d")
И далее вставляй log.debug(...) куда только захочешь.
Представь себе включение отладки для определенного пользователя - в sip.conf ставишь setvar=log_level=debug, и все звонки он него трассируются. И ты сам волен в любой момент воткнуть logger.debug(...) в любую ветку алгоритма или между любыми командами.

Надо проверить...

28.10.2015

DialPlan в устройствах Linksys

Сегодня пришлось малость переделать DialPlan в 2102 но как-то подзабыл что за то отвечает.
Поэтому для памяти взял у IGORG
Оригинал

 
Диалплан представляет из себя последовательность шаблонов, разделённых вертикальной чертой '|' и ограниченных круглыми скобками. Для каждой линии может задаваться свой диалплан (параметр Dial_Plan). Для устройств, где присутствуют FXO порты (например, SPA3102 и AG310), настроек с диалпланами гораздо больше (по 2 на каждый PIN, используемый для авторизации), в названиях есть аббревиатура DP, перечислять не буду. Есть ограничение на длину параметра, что-то около 256 или 128 символов, сейчас не могу найти точную информацию.
Следует заметить, что все коды дополнительных сервисов, сконфигурированных на устройстве, автоматически добавляются к диалплану, и их не нужно учитывать в записи параметра.
Запись последовательности цифр
Основой записи являются обозначения для записи последовательности набранных цифр. Последовательность цифр записывается с помощью нескольких обозначений:
  1. Цифры набираемые с клавиатуры телефона: 0, 1, 2, 3, ..., 9, # и *. Заметьте, что использование символа # в диалплане может блокировать завершение набора с помощью этой клавиши.
  2. Последовательность цифр, заключённая в квадратные скобки, соответствует любому из заключённых в скобки символу.
    • Пр.: ([1239]) — соответствует любой из цифр 1, 2, 3 или 9
  3. Через тире может быть указан диапазон символов. Чаще всего используется внутри квадратных скобок.
    • Пр.: (1-5) — любая цифра от 1 до 5, ([1-39]) — пример из прошлого пункта, но записанный по-другому
  4. Символ X соответствует любому числу от 0 до 9
    • Пр.: (1XX) — любой трёхзначный номер, начинающийся на 1
  5. Если после символа поставлена точка, то считается, что этот символ может быть повторён любое количество раз (больше нуля)
    • Пр.: (810X.) — международный номер, с любым количеством цифр
Настройки, влияющие на обработку диалплана
  • Interdigit Long Timer — время ожидания ввода следующей цифры в том случае если нет подходящих под набранную комбинацию шаблонов
  • Interdigit Short Timer — время ожидания ввода следующей цифры, если есть один или более подходящий шаблон
  • Enable IP Dialing — разрешает использование в диалплане также и прямых ip-адресов для набора номера, примеры ниже.
Дополнительные возможности:
  1. Замена набранной последовательности. Синтаксис: <arg1:arg2>. Возможность позволяет заменить набранную последовательность на любую последовательность набираемых символов. При этом второй аргумент должен быть указан определённым значением, оба аргумента могут быть пустыми.
    • Пр.: (<83812:> XXXXXX) — данная запись будет соответствовать набранным цифрам 83812, но эта последовательность будет опущена и передана на SIP сервер не будет.
  2. Вставка тона в набор. При выходе на межгород или, в офисных станциях, на город привычно слышать КПВ, что можно реализовать вставкой запятой в нужную позицию последовательности цифр.
    • Пр.: (8, 770) — при наборе номера 8770 после цифры 8 будет выдан непрерывный тон
  3. Запрет набора номера. Если в конце шаблона номера добавить восклицательный знак '!', то набор номеров, соответствующих шаблону будет заблокирован.
    • Пр.: (8 10X xxxxxxx ! | 8 xxx xxxxxxx ) — разрешает набор только междугородних номеров и исключает международные вызовы
  4. Замена значений таймеров набора номера. Значения таймеров могут быть назначены как для всего диалплана, так и для определённого шаблона.
  • Буква S отвечает за установку Interdigit Short Timer, а L — Interdigit Long Timer
  • Значение таймеров может быть указано для всех шаблонов в диалплане, если значение перечислены до открывающейся круглой скобки (если указано только значение короткого таймера, то обязательно должна присутствовать запятая после значение, как показано в примере). Пр.: S:4, (8XXX.) или S:4,L:8 (XXX)
  • Если эти значения указаны только в одной из последовательностей, то действуют только для неё. Так же в этом случае не надо ставить двоеточие между ключём и значением таймаута, значение может быть расположено в любом месте шаблона. Пр.: (S4 8XXX. | XXX) или ([1-5] XX S0) — вызовет мгновенную передачу вызова при наборе трехзначного номера, начинающегося на 1,2, ... , 5.
  • Так же в некоторую последовательности может быть вставлена пауза (ключ P)
Набор по прямому адресу (IP Dialing)

Символ @ поставленный после номера означает что далее будет указан адрес сервера, на который будет отправлен вызов на набранный номер. Лучше всего, если используется IP Dialing разрешить так же приём и передачу вызовов без регистрации (Call Without Reg, Answer Without Reg). Может помочь в случае отказа сервера :)
Для шлюзов SPA3102 вместо адреса может быть использовано ключевое слово gw0, тогда вызов пойдёт через PSTN линию. Адреса gw1, ... , gw4 используются для шлюзов заданных в Gateway1-4. Так же для авторизации на серверах прямо в диалплане могут быть указаны параметры usr, pwd, nat.
Кроме того формат адреса с IP Dialing может быть использован в номерах, предназначенных для переадресации звонков.
Примеры:
  • ( 8 xxx xxxxxxx ) — 11-значный номер, начинающийся на 8.
  • ( 8 xxx xxxxxxx | <:8495> xxxxxxx ) — 11-значный номер, начинающийся на 8, если введён 7-ми значный, то добавить к передаваемому номеру 8495. Очень удобно делать набор локальных номеров через SIP провайдера вроде SIPNET.
  • ( 0[123] | 8 [2-9]xx [2-9]xxxxxx ) — набор номеров экстренных служб, а так же некоторого странного набора междугородних номеров
  • ( S0 <:82125551234> ) — быстрый набор указанного номера, аналог режима хотлайн на других шлюзах
  • ( P5 <:1000> | xxxx ) — такой диал-план позволяет набрать любой номер, состоящий из цифр, а если ничего не введено в течении 5 секунд вызвать номер 1000 (пусть это будет секретарь)
  • Звонить с первой линии на вторую линию устройства: (<02:3463463@192.168.254.254:5061>). С учётом что аккаунт на второй линии 3463463, устройство настроено с использованием указанного IP адреса и номером порта на второй линии.

Transfer

Взято у IGORG, чтоб не забыть.
Оригинал


Самой важной задачей, которую выполняет АТС предприятия — принять звонок, передать необходимому сотруднику и совершить обмен информацией. Совершенно неприемлемой ситуацией является, когда звонок по какой-либо причине теряется. Лояльности это уж точно не добавит.
Одной из важнейших функций PBX является функция перевода вызова, которая, к сожалению в Asterisk работает не так, как, скажем, в традиционном для российского офиса Panasonic. В этом я убедился устанавливая Asterisk в компании на 60 человек, в которой эта функция была критична, но не работала как надо ни на адаптерах, ни на Asterisk. Решилось тогда административными мерами: человек, переводящий звонок, должен был дождаться ответа третьей стороны. Но это не решение, решение далее.
В версии 1.6 усилиями разработчиков появилась функция, позволяющая возвращать вызов сотруднику, делавшему перевод вызова, если на другой стороне вызов принят не был. При этом при возврате вызова Asterisk может сделать несколько вызовов, ведь он может уже быть занят новым разговором. Вот опции, отвечающие за работу:
  • atxferdropcall. Допустим кто-либо осуществляет перевод вызова с согласованием и ложит трубку до того как вызов соединён. Если выбрано значение «yes», то используется старое поведение — при невозможности соединить позвонившего вызов сбрасывается. Если выбрано «no», то система вернёт вызов обратно осуществлявшему transfer.
  • atxfernoanswertimeout. Таймаут, в течении которого система пытается соединиться со третей стороной. По-молчанию 15 секунд.
  • atxferloopdelay. Задержка перед повторным возвратом вызова делавшему transfer сотруднику.
  • atxfercallbackretries. Количество попыток возврата вызова, по-умолчанию 2.
Оказывается можно сделать аналогичным образом и в 1.4 с помощью только функций и переменных диал-плана. Вот пример extensions.conf:
  1. [globals]  
  2. XFERNOANSTIMEOUT=15  
  3. XFERRETRIES=2  
  4. XFERLOOPDELAY=10  
  5.   
  6. [office]  
  7. exten => _XXX,1,Set(TRANSFER_CONTEXT=office-xfer)  
  8. exten => _XXX,n,Dial(SIP/${EXTEN},,Tt)  
  9. [office-xfer]  
  10. exten => _XXX,1,Set(RETRIES=0)  
  11. exten => _XXX,n,ChanIsAvail(SIP/${EXTEN},s)  
  12. exten => _XXX,n,GotoIf($[${LEN(${AVAILCHAN})} = 0]?ret)  
  13. exten => _XXX,n,Dial(SIP/${EXTEN},${XFERNOANSTIMEOUT},Tt)  
  14. exten => _XXX,n(ret),GotoIf($[${BRIDGEPEER} = ${TRANSFERERNAME}]?(h,1))  
  15. exten => _XXX,n,Dial(SIP/${TRANSFERERNAME:4:3},${XFERNOANSTIMEOUT},Tt)  
  16. exten => _XXX,n,Set(RETRIES=$[${RETRIES}+1])  
  17. exten => _XXX,n,GotoIf($[${RETRIES} < ${XFERRETRIES}]?ret)  
  18. exten => _XXX,n,Wait(${XFERLOOPDELAY})  
  19. exten => _XXX,n,Playback(sorry)  
  20. exten => _XXX,n,Hangup()  
  21. exten => h,1,Hangup()  
Такое решение более гибко, чем настройки в features.conf, так как вы можете вместо обратного вызова припарковать клиента или отправить сообщение менеджеру на Jabber о том, что перевод вызова не удался.
В приведённом примере достаточно много шелухи, если постараться то все дополнения уместятся в три-четыре строки. Ключевым здесь является использование переменной. Вот ещё некоторые переменные, которые вы можете использовать:
  • BRIDGEPEER — переменная с именем канала, в данный момент соединённого с данным
  • BLIND_TRANSFER — переменная с именем пира, осуществившего перевод вызова в-слепую
  • TRANSFERERNAME — переменная содержащая имя канала. осуществляющего transfer (это относится только к attented transfer)
 

RHVoice установка

Требуемые пакеты: scons flite libunistring pkgconfig libsndfile libsamplerate pulseaudio и свежий gcc
Исходники берем здесь https://github.com/Olga-Yakovleva/RHVoice

Дальше все по инструкции:
https://github.com/Olga-Yakovleva/RHVoice/wiki/Building-on-Linux-%28Russian%29

scons
scons install
ldconfig

Проверка
echo "Хотите выключить свет на кухне?" | RHVoice-test -p Elena -o 1.wav




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

Озвучивает намного лучше чем Festival и Espeak.

22.10.2015

Espeak + Asterisk


Для установки Easpeak на Gentoo требуется:

emerge -pv libsndfile libsamplerate

USE="flac ao id3tag wavpack mp3rtp" CPU_FLAGS_X86="mmx sse" emerge -vp espeak

Либо тащим с http://espeak.sourceforge.net/
App для астера берем с http://asterisk-espeak.sourceforge.net/ либо http://zaf.github.io/Asterisk-eSpeak/
оно же https://github.com/zaf/Asterisk-eSpeak

Последовательность установки:
Астер, espeak, libsndfile, libsamplerate, app_espeak


Описание чего делать с espeak  чтоб он нормально говорил лежит вот тут http://archlinux.org.ru/forum/topic/8621/?page=2


Качество очень сильно проигрывает RHvoice.

27.05.2015

Макрос записи.

Макрос записи разговора.


Переменные ${CALLFILENAME},${monopt} выставляются в основном диалплане.
Надо переделать чтоб выставлялись в макросе.
[macro-en-record-test]
exten => s,1,NoOp(CHANNEL(from):${CHANNEL(from)})
exten => s,n,MYSQL(Connect connid localhost user pass db)
exten => s,n,MYSQL(Query resultid ${connid}  SELECT `record`  FROM `sippeers` WHERE defaultuser = '${CHANNEL(peername)}')
exten => s,n,MYSQL(Fetch fetchid ${resultid} record )
exten => s,n,MYSQL(Clear ${resultid})
exten => s,n,MYSQL(Disconnect ${connid})

exten => s,n,Gotoif($["${record}" = "no"]?dis-rec)
exten => s,n,Gotoif($["${record}" = ""]?dis-rec)
exten => s,n(monitor),MixMonitor(${CALLFILENAME}.wav,b,${monopt});

exten => s,n,MacroExit
exten => s,n(dis-rec),MacroExit
exten => s,n,Hangup

Макрос включения/выключения абонента


Макрос включения/отключения абонента.

[macro-en-peer]
exten => s,1,NoOp(CHANNEL(from):${CHANNEL(from)})
exten => s,n,MYSQL(Connect connid localhost user pass db)
exten => s,n,MYSQL(Query resultid ${connid}  SELECT `enable_peer`  FROM `sippeers` WHERE defaultuser = '${CHANNEL(peername)}')
exten => s,n,MYSQL(Fetch fetchid ${resultid} enable_peer )
exten => s,n,MYSQL(Clear ${resultid})
exten => s,n,MYSQL(Disconnect ${connid})
exten => s,n,Gotoif($["${enable_peer}" = "no"]?dis-peer)
exten => s,n,MacroExit
exten => s,n(dis-peer),Congestion(10)
exten => s,n,Hangup

 

15.04.2015

IVR-стандартный

Это стандартный IVR  для работы с пачкой виртуальных АТС на одном сервере.
same => n,Set(TIMEOUT(digit)=5)  ; Set Digit Timeout to 5 seconds
same => n,Set(TIMEOUT(response)=5)  ; Set Response Timeout to 10 seconds
same => n,Read(EXT,/sound/${CONTEXT:3}/ivr/name_file,3)
same => n,GotoIf($["${LEN(${EXT})}" = "3"]?vnum)
same => n,GotoIf($["${EXT}" = "1"]?num1)
same => n,GotoIf($["${EXT}" = "2"]?num2)
same => n,GotoIf($["${EXT}" = "3"]?num3)
same => n,GotoIf($["${EXT}" = "4"]?num4)
same => n,GotoIf($["${EXT}" = "5"]?num5)
same => n,GotoIf($["${EXT}" = "6"]?num6)
same => n,Dial(Local/101@out_${CONTEXT:3}/n&Local/102@out_${CONTEXT:3}/n&Local/103@out_${CONTEXT:3}/n)
same => n,Hangup

same => n(num1),Dial(Local/101@out_${CONTEXT:3}/n&Local/102@out_${CONTEXT:3}/n&Local/103@out_${CONTEXT:3}/n)
same => n,Hangup
same => n(num2),Dial(Local/201@out_${CONTEXT:3}/n&Local/202@out_${CONTEXT:3}/n&Local/203@out_${CONTEXT:3}/n)
same => n,Hangup
same => n(num3),Dial(Local/304@out_${CONTEXT:3}/n&Local/305@out_${CONTEXT:3}/n)
same => n,Hangup
same => n(num4),Dial(Local/304@out_${CONTEXT:3}/n&Local/305@out_${CONTEXT:3}/n)
same => n,Hangup

same => n(num5),Dial(Local/303@out_${CONTEXT:3}/n)
same => n,Hangup
          same => n(vnum),Dial(Local/${EXT}@out_${CONTEXT:3}/n)
          same => n,Hangup


05.03.2015

Макрос переадресации


Макроc переадресации:
Работает при выставление времени в 0 как безусловная.
Если время не 0 то по не ответу.


[macro-redirect-time]
exten => s,1,NoOp(CHANNEL(from):${CHANNEL(from)})
same => n,MYSQL(Connect connid localhost user pass db)
same => n,MYSQL(Query resultid ${connid}  SELECT `r_callerid`,`r_number`,`r_time`  FROM `redirect` WHERE client = '${CUT(ARG1,_,2)}' AND  r_callerid = '${ARG2}')
same => n,MYSQL(Fetch fetchid ${resultid} r_callerid r_number r_time)
same => n,MYSQL(Clear ${resultid})
same => n,MYSQL(Disconnect ${connid})
same => n,GotoIf($["${r_number}" = ""]?rtime)
same => n,GotoIf($["${r_time}" = "0"]?redir:rtime)
same => n(rtime),NoOp(Mark RTIME)
same => n,Dial(SIP/${CUT(ARG1,_,2)}${ARG2},${r_time},Tt)
same => n,GotoIf($["${r_time}" = ""]?exit)
same => n,GotoIf($["${r_time}" = "0"]?exit)
same => n(redir),NoOp(Mark REDIR)
same => n,Dial(Local/${r_number}@${ARG1})
same => n(exit),MacroExit
Вызывается  exten => _XXX,n,Macro(redirect-time,${CONTEXT},${EXTEN})

База в MySQL:

CREATE TABLE `redirect` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `r_callerid` decimal(3,0) DEFAULT '0',
  `r_number` decimal(11,0) DEFAULT '0',
  `r_time` decimal(3,0) NOT NULL DEFAULT '120',
  `client` varchar(20) DEFAULT NULL,
   PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

15.02.2015

Realtime + NAT

Наткнулся на  баг  в версии 11.6.0. описанный в ASTERISK-20572, сказано что пофиксили еще в версии 11.1.
 Патч не подходит.
Заменить в chan_sip.c строку:
  • if ((!found && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) || !peer->host_dynamic) { 
 на:
  •  if (((!found && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) || !peer->host_dynamic) && !realtime ) {
Но при выполнении входящего звонка на этот пир сразу после sip reload вызов проходить не будет так как пир появляется в кеше со статусом UNREACHABLE.
Как лечить пока не разобрался. В виде костыля можно уменьшить время регистрации до 120 секунд. Но для определенных клиентов это очень критично.