Проброс внешней сети через GRE туннель.

Имеем схему следующую схему, на ММТС-9 есть коммутатор Cisco 4948 IOS cat4500-entservicesk9-mz.150-2.SG. Который подключается к интернету через протокол BGP, на коммутаторе прописана сеть 1.1.0.0/23. IP адрес коммутатора 1.1.0.1

Есть удаленная точка которая подключена к местному провайдеру через маршрутизатор Cisco 2811. Стоит задача выдавать клиентам публичные ip адреса из сети 1.1.0.0/23

Есть 2 варианта решения этой задачи, это смаршрутизировать подсеть через VPN туннель или через L2TPv3 (L2 Tunnel over IP). Рассмотрим первый вариант. Будем использовать GRE туннель

писана сеть 1.1.0.0/23. IP адрес коммутатора 1.1.0.1

 

Есть удаленная точка которая подключена к местному провайдеру через маршрутизатор Cisco 2811. Стоит задача выдавать клиентам публичные ip адреса из сети 1.1.0.0/23.

 

Есть 2 варианта решения этой задачи, это смаршрутизировать подсеть через VPN туннель или через L2TPv3 (L2 Tunnel over IP). Рассмотрим первый вариант. Будем использовать GRE туннель. Схема показана на рисунке

Настройка Cisco 4948

# conf t

(config)# interface Tunnel0

(config-if)# ip address 10.10.10.1 255.255.255.0

(config-if)# ip tcp adjust-mss 1436

(config-if)# tunnel source 1.1.0.1

(config-if)# tunnel destination 2.2.2.2


Cisco 2811:

# conf t

(config)# interface Tunnel0

(config-if)# ip address 10.10.10.2  255.255.255.0

(config-if)# ip tcp adjust-mss 1436

(config-if)# tunnel source 2.2.2.2

(config-if)# tunnel destination 1.1.0.1


Мы создали на свиче и маршрутизаторе  интерфейсы  Tunnel0, в нём указали с помощью ip address внутреннюю адресацию туннеля – тот есть это адреса инкапсулированного IP, а с помощью команд tunnel source и tunnel destination мы указали параметры транспортного протокола IP (внешнего). У нас появилась новая сеть, которая виртуально соединяет напрямую два устройства.

Если все правильно настроено, то свич и маршрутизатор должны друг друга «видеть».

Далее настраиваем интерфейсы на Cisco 2811

Интерфейс для выхода в интернет:

# conf t

(config)# interface FastEthernet0/0

(config-if)# ip address 2.2.2.2 255.255.255.252

(config-if)# ip virtual-reassembly

(config-if)# no cdp enable


Настраиваем маршрутизацию:

Cisco 2811

Шлюз по умолчанию

(config)# ip route 0.0.0.0 0.0.0.0 2.2.2.1

Создаем access-list в котором будут разрешены наши ip адреса.

(config)# ip access-list standard PublikIP

(config-std-nacl)# permit 1.1.1.16 0.0.0.15


route-map  который «навешиваем на наш интерфейс»

(config)# route-map DEFAULT permit 10 

(config-route-map)# match ip address PublikIP

(config-route-map)# set ip next-hop   10.10.10.1


Интерфейс  с ip адресами из нашей сети, он же будет default gateway для пользователей

(config)# interface FastEthernet0/1

(config-if)# ip address 1.1.1.17  255.255.255.240

(config-if)# ip policy route-map DEFAULT

(config-if)# ip virtual-reassembly

(config-if)# no cdp enable

На Cisco 4948 маршрутизация настраивается очень просто

(config)# ip route 1.1.1.16 255.255.255.240 10.10.10.2

Все теперь клиенты могут настраивать у себя ip адреса  1.1.1.18-1.1.1.30 маска 255.255.255.240 и шлюз 1.1.1.17.



2018-10-01T12:22:25
Cisco

Сообщение IP_VFR-4-FRAG_TABLE_OVERFLOW Ошибка «IP_VFR-4-FRAG_TABLE_OVERFLOW и ip virtual-reassembly»

в логах маршрутизатора появилось такое сообщение:

%IP_VFR-4-FRAG_TABLE_OVERFLOW: GigabitEthernet0/1: the fragment table has reached its maximum threshold 64 %IP_VFR-4-TOO_MANY_FRAGMENTS: GigabitEthernet0/1: Too many fragments per datagram (more than 32) — sent by *.*.*.*, destined to *.*.*.*

%IP_VFR-4-FRAG_TABLE_OVERFLOW : [chars]: the fragment table has reached its maximum threshold [dec]

Explanation: The number of datagrams being reassembled at any one time has reached it maximum limit.

Recommended Action: Increase the maximum number of datagrams that can be reassembled by entering the ip virtual-reassembly max-reassemblies number command, with number being the maximum number of datagrams that can be reassembled at any one time.

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

Рекомендуемые действия: увеличить максимальное число датаграмм которые могут быть собраны, путем ввода команды ip virtual-reassembly с числом максимального количества датаграмм, которые могут быть собранны в промежуток времени.

Небольшое пояснение:

IP пакеты фрагменируются и буферизруются маршрутизатором, до тех пор пока не соберутся в датаграмму и в конце концов не передадутся. Маршрутизатор распределяет пространство для количества датаграмм (и фрагментов на датаграмму) которые ждут сборки. Вы можете увеличить размер таблицы фрагменов, но так же стоит выяснить что вызывает фрагментацию. Это могут быть значения MTU, действия злоумышленника с целью забить всю память фрагментами пакетов или не корректной настройкой оборудования.

выдержка из документации с cisco.com по синаксису команды ip virtual-reassembly: Что бы включить сборку виртуальных фрагментов (VFR) на интерфейсе, используйте команду ip virtual-reassembly в режиме конфигурации интерфейса. Что бы отключить VFR нужно использовать no с это командой.

синтаксис:

ip virtual-reassembly [max-reassemblies number] [max-fragments number] [timeout seconds] [drop-fragments]

no ip virtual-reassembly [max-reassemblies number] [max-fragments number] [timeout seconds] [drop-fragments]

max-reassemblies number: (Опционально) Максимальное колчество IP датаграмм, которые могут быть собранны в заданное время. Значение по умолчанию: 16.

Если достигнуто максимальное значение, то все последующие фрагменты будут отбрасываться и в системный журнал будут отправлены тревожные сообщения.

max-fragments number: (Опционально) Максимальное количество фрагментов на одну IP датаграмму (фрагмент). Значение по умолчанию: 32.

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

timeout seconds: (Опционально) значение таймаута в секундах для сборки IP датаграммы. Значение по умолчанию: 3.

Если IP датаграмма не получит все фрагменты в установленное время, то IP датаграмма (и все ее фрагменты) будет отброшена.

drop-fragments: (Опционально) Включает функцию VFR отбрасывать все пакеты, которые приходят на сконфигурированный интерфейс. По умолчанию эта функция отключена. Использование: Когда злоумышленник продолжительное время посылает большое количество дефектных пакетов, может быть осуществлена атака переполнения буфера. Firewall теряет время и память когда пытается пересобрать фейковые пакеты.

Опции max-reassemblies и max-fragments позволяют вам сконфигурировать максимальные пороговые значения, и предотвратить атаку переполнения буфера и контролировать потребление потребление памяти.

В дополнение к конфигурированию максимальных попроговых значений, каждая IP датаграмма ассоциируется с управляемым таймером. Если IP датаграмма не получит все фрагменты через указанный период (который можно установить опцией timeout), время истечет и IP датаграмма (со всеми фрагментами) будет отброшена.

Автоматическое включение и выключение VFR: VFR реализвана для работы с любой функцией которая использует сборку фрагментов (таких как Cisco IOS firewall и NAT). В данный момент NAT включает и выключает VFR автоматически. т.е. когда NAT включен на интерфейсе, то на этом интерфейсе автоматически включена VFR.

Если более чем одна функция пытается автоматически включить VFR на интерфейсе, VFR начинает вести учет функций использующих его, и когда это количество становится равным нулю — он автоматически отключается.



2018-10-01T12:20:23
Cisco

Резервирование сервера Elastix с помощью heartbeat и rsync

Одним из простых способов построения отказоустоичивой системы телефонии на основе elastix является использование heartbeat для резервироания серверов и rsync для синхронизации конфигурации. Для начала устанавливаем и настраиваем heartbeat и rsync.

После настройки heartbeat и rsync создаем на основном сервере файл mysqldump.sh

mysqldump -u root -ppassword asterisk > /home/backup/asterisk.sql

mysqldump -u root -ppassword asteriskcdrdb > /home/backup/asteriskcdrdb.sql

mysqldump -u root -ppassword meetme > /home/backup/meetme.sql

cp /etc/sysconfig/iptables /home/backup/

Изменяем права на запуск:

chmod 750 /home/mysqldump.sh

Добавляем его в cron, для этого в файл /var/spool/cron/root добавляем строчку

00 00 * * * * /home/mysqldump.sh

Перезапускаем крон.

/etc/init.d/crond restart

На резервном сервере создадим скрипт который будет синхронизировать конфигурацию с основным сервером.

nano /home/sync_config.sh

Его содержание

rsync  -rc --exclude=Thumbs.db -t -e ssh --rsync-path=/usr/bin/rsync --temp-dir=/tmp root@server1:/home/backup/ /home/backup

rsync  -rc --exclude=Thumbs.db -t -e ssh --rsync-path=/usr/bin/rsync --temp-dir=/tmp root@server1:/etc/asterisk/ /etc/asterisk

rsync  -rc --exclude=Thumbs.db -t -e ssh --rsync-path=/usr/bin/rsync --temp-dir=/tmp root@server1:/var/lib/asterisk/ /var/lib/asterisk

rsync  -rc --exclude=Thumbs.db -t -e ssh --rsync-path=/usr/bin/rsync --temp-dir=/tmp root@server1:/var/spool/asterisk/monitor/ /var/spool/asterisk/monitor

mysql -u root -ppassword asterisk < /home/backup/asterisk.sql

mysql -u root -ppassword meetme < /home/backup/meetme.sql

mysql -u root -ppassword meetme < /home/backup/asteriskcdrdb.sql

cp /home/backup/iptables /etc/sysconfig/iptables service iptables restart /bin/asterisk.reload

Изменяем права

chmod 750 /home/sync_config.sh

И тоже добавляем его в cron

30 00 * * * * /home/sync_config.sh

Для корректной работы астериска, нужно прописать в  /etc/asterisk/sip.conf

bindaddr=192.168.0.12

Где 192.168.0.12 — общий ip адрес на который переключается сервер с помощью heartbeat.

Для этого в WEB интерфейсе elastix заходим во вкладку PBX->Unembedded freePBX. И на вкладке Tools в меню Asterisk Sip Seting в самом низу есть строка «Bind Address». Здесь прописываем наш адрес.

Так же настраиваем авторизацию по ключу. Чтобы работала синхронизация конфигурации через cron.



2018-10-01T12:04:16
Asterisk

Что такое DSL (Digital Subscriber Line) и как это работает

Цифровая абонентская линия (DSL) — это технология высокоскоростного Интернета, которая позволяет передавать цифровые данные по проводам телефонной сети. DSL не мешает телефонной линии; одна и та же линия может использоваться как для Интернет, так и для обычных телефонных служб. Скорость загрузки DSL колеблется между 384 Кбит/с и 20 Мбит/с. Самой популярной реализацией DSL сегодня является Асимметричная цифровая абонентская линия (ADSL). Это асимметрично, потому что скорость загрузки и загрузки не одинакова (не синхронизирована). Загрузка обычно происходит намного медленнее, чем загрузка, поскольку она обычно не так необходима, как высокая скорость загрузки.

Следует отметить, что расстояние, на которое данные должны перемещаться, несколько снижает скорость загрузки и загрузки. Современный ADSL может обрабатывать 24 Мбит / с на 2-километровом участке провода. Однако, когда провод имеет длину более 2 километров (или что-то большее, чем 1,25 мили), передача данных уменьшается. Именно из-за этого, в то время как ADSL может иметь большую скорость загрузки, чем дальше человек от поставщика услуг, тем меньше вероятность того, что он получит. Поэтому поставщики услуг склонны рекламировать низкий бал, но потребитель может получить больше. Все зависит от расстояния, которое должна пройти информация по медным проводам.

DSL разделяет частоты, используемые в одиночной телефонной линии, на две основные полосы. Высокочастотный диапазон используется для отправки данных ISP, а низкочастотная полоса используется для отправки речевых данных. Благодаря этой технологии мы можем наслаждаться доступом в Интернет, одновременно пользуясь телефоном. DSL можно легко установить и работать вместе с любым существующим оборудованием для вашей стандартной телефонной линии.

Обычный DSL

Обычная DSL — это стандартная форма DSL, которая требует передачи существующей наземной линии передачи данных и голоса. В обычной DSL клиенты обычно объединяют телефон и Интернет вместе и имеют доступ одновременно. Голосовые сигналы передаются по проводам на гораздо более низкой частоте, чем сигналы данных, и, таким образом, позволяют передавать данные, не мешая речевым сигналам по той же линии.

Naked DSL

В naked DSL клиенты не обязаны иметь существующую стационарную связь, имеющую доступ к Интернету. Это позволяет клиентам отказаться от дополнительных сборов, связанных с стационарными телефонами, и переключиться в первую очередь на их план сотового телефона. Было много споров по поводу naked DSL, но неизбежно, многие провайдеры телефонов были вынуждены предложить его в рамках своих упакованных планов.

Настройка DSL

Для DSL-сервиса необходим DSL-модем (известный как DSL-приемопередатчик) для подключения к телефонной линии или разъему. Затем DSL-модем подключается к компьютеру. В конце телефонной линии телефонная линия подключается к цифровому мультиплексору доступа к абонентской линии (DSLAM). DSLAM — это в основном сетевое устройство, которое подключает несколько линий DSL к высокоскоростному интернет-магистрали.

DSL-модем, DSLAM и компьютер должны быть синхронизированы друг с другом, чтобы служба DSL работала должным образом. Процесс синхронизации выглядит следующим образом:

  • Когда модем DSL включен, он проходит самотестирование.
  • Затем DSL-модем проверяет свое соединение с компьютером через порт Ethernet или USB.
  • Затем DSL-модем пытается синхронизировать с DSLAM.

Процесс синхронизации обычно длится несколько секунд. В модемах DSL есть индикатор, обозначенный как DSL или LINK. Если процесс синхронизации будет успешным, зеленый индикатор останется включенным.

Технологии DSL

Было много версий DSL, поскольку за эти годы это было многократно обновлено. Ниже приведен полный список версий и типов DSL, которые стали доступны для общественности.

Цифровая абонентская линия ISDN

Цифровая абонентская линия ISDN была одной из первых форм DSL и использовала технологию, известную как ISDN для передачи сигналов.

Цифровая абонентская линия с высокой скоростью передачи данных

Цифровая абонентская линия с высокой скоростью передачи данных была первым устройством DSL, которое использовало витые медные кабели для передачи сигналов в высокочастотном спектре.

Симметричная цифровая абонентская линия

В Symmetric Digital Subscriber Line одинаковое количество данных загружается и загружается в любой момент времени.

Симметричная высокоскоростная цифровая абонентская линия

Симметричная высокоскоростная цифровая абонентская линия была создана для более быстрой замены Symmetric Digital Subscriber Line.

Асимметричная цифровая абонентская линия

В Асимметричной цифровой абонентской линии загружается больше информации, чем загружается в любой момент времени.

Асимметричная цифровая абонентская линия 2

Асимметричная цифровая абонентская линия 2 обеспечивала качество, которого не хватало предшественнику.

Асимметричная цифровая абонентская линия 2 Plus

Асимметричная цифровая абонентская линия 2 Plus увеличила скорость передачи данных DSL на 200%.

Асимметричная цифровая абонентская линия Plus Plus

Асимметричная цифровая абонентская линия Plus Plus была создана в Японии и увеличила скорость передачи данных DSL до 50 мегабит в секунду и увеличила спектр, используемый для 3,75 мегагерц.

Адаптивная цифровая абонентская линия

Адаптивная цифровая абонентская линия используется для снижения скорости при увеличении диапазона и производительности сигнала.

Высокоскоростная цифровая абонентская линия

Высокоскоростная цифровая абонентская линия была просто более быстрой версией предыдущих моделей.

Высокоскоростная цифровая абонентская линия 2

Высокоскоростная цифровая абонентская линия 2 была изобретена для замены уже увеличенных скоростей высокоскоростной цифровой абонентской линии.

Etherloop

Etherloop — это технология, позволяющая использовать кабель Ethernet для передачи данных и голоса по телефонной линии.

Uni-DSL

Uni-DSL — это система, внедренная Texas Instruments, которая работает со всеми формами DMT, который представляет собой метод разделения частот на высокие и низкие сигналы, позволяющий передавать данные и голос по одному и тому же проводу одновременно.

Гигабитная цифровая абонентская линия

Гигабитная цифровая абонентская линия предлагает скорости, которые раньше никогда не видели в сообществе DSL, способных передавать данные со скоростью примерно 128 Мбит / с.

Универсальная цифровая абонентская линия с высокой скоростью передачи данных

Универсальная цифровая абонентская линия с высоким битрейтом — это новейшая версия DSL и является примером волоконно-оптической технологии. Цифровая абонентская линия универсальной высокой скорости передачи данных обеспечивает чрезвычайно быструю скорость и надежное обслуживание при правильной установке.

ADSL (асинхронный DSL)

ADSL (асимметричный DSL) — это тип DSL, где пропускная способность по восходящему и нисходящему каналам назначается различной пропускной способностью. Типичные конфигурации сегодня — 2 Мбайт ниже по течению и 128 КБ вверх по течению.

Downstream — это данные, которые вы загружаете по сети в локальные системы. Upstream — это данные, которые вы отправляете из своих локальных систем по всей сети.

IDSL (ISDN через DSL)

IDSL (ISDN через DSL) является стандартом 144Kb для DSL. IDSL используется, когда другие типы DSL недоступны. IDSL работает медленно и относительно дорого, но иногда это может быть наилучшим вариантом.

RADSL (адаптируемая скорость DSL)

RADSL (Rate Adaptive DSL) — это асимметричный DSL-вариант, который может регулировать скорость DSL-соединения в зависимости от расстояния от центрального офиса (CO) и качества соединения.

SDSL (симметричный DSL)

SDSL (однолинейная DSL) — это тип DSL, в котором восходящий и нисходящий каналы настроены на одну и ту же полосу пропускания. SDSL обычно работает на скорости 1,5 Мбит / с вверх и вниз по течению.

VDSL (очень высокая скорость передачи DSL)

VDSL (очень высокая скорость передачи данных DSL) — это асимметричная версия DSL, которая работает на очень высоких скоростях, но только на расстоянии до 1000 футов от центрального офиса (CO).

DSL Lite

DSL Lite — это асимметричный вариант DSL, который размещает разделитель DSL в центральном офисе telco, а не в помещении клиента.

G.SHDSL (однопарная высокоскоростная DSL)

G.SHDSL (однопарная высокоскоростная цифровая абонентская линия) представляет собой вариант SDSL, который определен стандартом МСЭ G.991. Он работает на симметричных скоростях от 192 Кбит / с до 2304 Кбит / с по одной линии и 384 Кбит / с — 4608 Кбит / с по двум парам.

Европейцы относятся к G.SHDSL как «SDSL», вызывая путаницу с существующим оборудованием SDSL.

DSL-фильтры

В большинстве домов есть две пары проводов от местной телефонной компании. Если в доме используется только одна телефонная линия, DSL можно установить на вторую пару.

Если в доме используются обе телефонные линии, DSL должен использовать одну проводную пару с голосовым трафиком. Это делается с использованием фильтра DSL.

Фильтр DSL представляет собой небольшую коробку, прикрепленную к проводной паре, чтобы разделить ее на две отдельные пары проводов — одну для голосового трафика, а другую для трафика DSL.



2018-10-01T09:57:07
Вопросы читателей

FreePBX, Elastix. Уведомление о пропущенных вызовах

Очень часто, когда возникают большие нагрузки на операторов, клиент может долго ожидать ответа и может не дождавшись положить трубку. В результате, потенциальный клиент до вас не дозвонился, но он обязательно дозвонится до кого-то из ваших конкурентов. Поэтому необходим своевременный отчет о таких пропущенных вызовах, чтобы можно было быстро перезвонить человеку.

Уведомления при потерянных вызовах на IVR

Если вызовы поступают на IVR, и звонящий не дождавшись ответа положил трубку, то для отчетов правим файл /etc/asterisk/extensions_override_freepbx.conf

# nano /etc/asterisk/extensions_override_freepbx.conf

 

[ivr-1] ;Номер ivr

exten => h,1,System(python /usr/local/bin/sendmail.py "Пропущенный вызов в ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)}с номера ${CALLERID(name)}")


Сохраняем и делаем reload астериска. Тепер. если позвонивший положит трубку слушая голосовое меню, то на почту прийдет уведомление. Сам  sendmail.py находится в конце статьи.

Уведомление в группах вызова

Если необходимо уведомлять о потерянных вызовах в группах вызова, то также правим файл /etc/asterisk/extensions_override_freepbx.conf

# nano /etc/asterisk/extensions_override_freepbx.conf

 

[ext-group]

exten => h,1,System(python /usr/local/bin/sendmail.py "Пропущенный вызов в ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)}с номера ${CALLERID(name)}")

exten => h,2,Macro(hangupcall,)

 Уведомление в очередях

Если же вызов поступает в очередь, то в /etc/asterisk/extensions_override_freepbx.conf  прописываем

[ext-queues]

exten => h,1,ExecIf($["${CDR(dstchannel)}"=""]?System(python /usr/local/bin/sendmail.py "Пропущенный вызов в ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} с номера ${CALLERID(name)}"))

exten => h,2,Macro(hangupcall,)

Сам файл sendmail.py

#!/usr/bin/python

# -*- coding: utf-8 -*-

from email.MIMEText import MIMEText

import smtplib

import sys

sender = 'noanswer@yourdomain.ru' # От кого

recivers = 'youremail' # Ваш e-mail

host = "localhost"

text = sys.argv[1]

msg = MIMEText(text, "", "utf-8")

msg["Subject"] = "Уведомление о пропущенном вызове"

smtpObj = smtplib.SMTP('localhost')

smtpObj.sendmail(sender, recivers, msg.as_string())

smtpObj.close()


Не забудте дать права на запуск

chmod 755 /usr/local/bin/sendmail.py



2018-09-29T23:30:16
Asterisk

Asetrisk, распознавание и генерации речи с помощью yandex speechkit

В этой статье я расскажу как с помощью asterisk и  yandex speechkit, можно организовать интерактивный диалог с помощью голоса. В качестве примера создадим систему для голосового сбора показаний счетчиков горячей и холодной воды, сразу скажу, что это просто пример, а не рабочая версия, просто здесь показана сама идея организации диалога.

Итак, настройка Asterisk, для простоты настраивать будем через ael:

На Астериске организован цикл while

1234567 => {

Answer;

Set(audio=/var/lib/asterisk/sounds/custom/enteraccount);

flag=1;

label=1;

while (${flag} = 1){

Background(${audio});

Record(/tmp/${UNIQUEID}label${label}.wav,3,20);

Agi(yandex.agi,/tmp/${UNIQUEID}, ${label});

label=${label}+1;



                  };



    };

В начале позвонившему проигрывается фудио файл «enteraccount» с просьбой назвать лицевой счет

На каждом шаге цикла, позвонившему человеку проигрывается аудио файл «audio», путь к которому получен из agi скрипта, далее записывается ответ, и путь к полученному записанному файлу отправляется agi скрипту, также в скрипт отправляется текущий шаг «label», после чего шаг увеличивается на 1, и цикл повторяется. Из agi скрипта астерис получает 2 параметра, это обязательный параметр «audio», путь к аудиофайлу который нужно проиграть, и не обязательный «label», метка с помощью которой происходит синхронизация астериска и agi. Выход из цикла происходит если человек положил трубку, а также если из agi прийдет параметр «flag» не равный 1.

Еще неплохо бы после завершения вызова удалить все временные файлы, для этого в макросе который срабатывает после завершения вызова пропишем

[macro-hangupcall]

exten => s,1,System(find /tmp/ -name "${UNIQUEID}*" | xargs rm);

На этом настройка астериска завершена.

Далее сам скрипт yandex.agi, написанный на python, для работы необходимо установить pyst

# wget http://heanet.dl.sourceforge.net/project/pyst/pyst/0.6.50/pyst-0.6.50.zip

# unzip pyst-0.6.50.zip

# cd pyst-0.6.50

# python setup.py install

Сам agi:

#!/usr/bin/python

# -*- coding: utf-8 -*-

import urllib2

import urllib

import sys

import random

from xml.dom.minidom import *

import os

import asterisk.agi



agi=asterisk.agi.AGI()

uuid=''

key='28b22b47-a7b0-40d2-892d-ad79bbdbc304'

def yadexASR(uuid, key, topic, callid):

# Функция для преобразования аудио файла в текст

# Генерим уникальный код id для запроса

    while (len(uuid)<32):

        uuid=uuid+random.choice('1234567890abcdef')

    #Ссылка для пост запроса 

    url = 'https://asr.yandex.net/asr_xml?uuid=%s&key=%s&topic=%s&lang=ru-RU' % (uuid, key, topic)

    filename = callid+'.wav'

    #Считываем файл в двоичном режиме

    audio = open(filename,'rb').read()

    #Указываем тип аудиофайла для заголовка в POST запрос

    headers={'Content-Type': 'audio/x-pcm;bit=16;rate=8000'}

    #Отправляем запрос

    request = urllib2.Request(url, data=audio, headers=headers)

    response = urllib2.urlopen(request)

    #Считываем ответ

    answer=response.read()

    # Создаем xml файл для полученного ответа

    f_answer=('%s.xml' % callid)

    f=open(f_answer, 'w')

    # записываем в файл ответ полученный на POST запрос (ответ получен в xml формате)

    f.write(answer)

    f.close()

    # Парсим xml файл

    xml = parse(f_answer)

    # Выбираем из файла значение между тегами variant

    var = xml.getElementsByTagName('variant')

    # Выбираем первое значение из xml файла, оно же наиболее точное в распознании

    result=var[0].childNodes[0].nodeValue

    return result



def generate(key,text, file):

# Функция для преобразования текста в аудио формат

    #Форматируем текс для GET запрса (нужен для корректной обработки кирилици)

    text_f=urllib.quote_plus(text.encode('utf-8'))

    #отправляем запрос на яндекс

    url='http://tts.voicetech.yandex.net/generate?text=%s&format=mp3&lang=ru-RU&speaker=jane&key=%s' % (text_f, key)

    # Сохраняем айдио файл в file

    urllib.urlretrieve(url, file)



if sys.argv[2].replace(' ','')=="1":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        # Распознаем полученный файл

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

        # Формируем ответ

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Вы сказали '+result+u'Скажите да или Нет', file+'.mp3')

        agi.set_variable('audio', file)

    except:

        agi.set_variable('audio', '/var/lib/asterisk/sounds/custom/enteraccount')

        agi.set_variable('label', '0')

        agi.verbose('label=0')



elif sys.argv[2].replace(' ','')=="2":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '1')

    if 'Да' in str(result.encode('utf-8')):

        agi.verbose('Yes')

        #///////////////////////////////

        # Здест должна быть проверка на существование абонента в базе данных

        #/////////////////////////////

    

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Показания какого счетчика вы хотите сообщить горячего или холодного?', file+'.mp3')

        agi.set_variable('audio', file)

    elif 'Нет' in str(result.encode('utf-8')):

        agi.verbose('No')

        # Ставим метку в 0 что бы вернуться к шагй 1 и проигрываем файл

        agi.set_variable('label', '0')

        agi.set_variable('audio', '/var/lib/asterisk/sounds/custom/enteraccount')

    else:

        agi.verbose('Error')

        # Если ответ не да и ни нет, говорим об ошибки и ставим метку на 1 что бы вернуться к шагу 2

        agi.set_variable('label', '1')

elif sys.argv[2].replace(' ','')=="3":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '2')

    if 'Горяч' in str(result.encode('utf-8')):

        agi.verbose('Hot')      

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Сообщите показания горячего счетчика', file+'.mp3')

        agi.set_variable('audio', file)

    elif 'Холод' in str(result.encode('utf-8')):

        agi.verbose('Cold')     

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Сообщите показания холодного счетчика', file+'.mp3')

        agi.set_variable('audio', file)

    else:

        agi.verbose('Error')

        agi.set_variable('label', '2')

elif sys.argv[2].replace(' ','')=="4":

    agi.verbose('label='+sys.argv[2].replace(' ',''))

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))      

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Ваши показания '+result+u'Скажите да или Нет', file+'.mp3')

        agi.set_variable('audio', file)

    except:

        agi.set_variable('label', '3')

        agi.verbose('label=3')

elif sys.argv[2].replace(' ','')=="5":

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '1')

    if 'Да' in str(result.encode('utf-8')):

        

        #/////////////

        #Обрабатываем результат и заносим в базу

        #/////////////

 

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Хотите сообщить показания другого счетчика да или нет?', file+'.mp3')

        agi.set_variable('audio', file)

    elif 'Нет' in str(result.encode('utf-8')):

        agi.set_variable('label', '2')

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Показания какого счетчика вы хотите сообщить горячего или холодного?', file+'.mp3')

        agi.set_variable('audio', file)

    else:

        agi.verbose('Error')

        agi.set_variable('label', '2')

elif sys.argv[2].replace(' ','')=="6":

    try:

        result=yadexASR(uuid, key, 'notes', sys.argv[1]+'label'+sys.argv[2].replace(' ',''))

    except:

        agi.set_variable('label', '1')

    if 'Да' in str(result.encode('utf-8')):

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Показания какого счетчика вы хотите сообщить горячего или холодного?', file+'.mp3')

        agi.set_variable('audio', file)

        agi.set_variable('label', '2')

    elif 'Нет' in str(result.encode('utf-8')):

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Досвидания', file+'.mp3')

        agi.set_variable('audio', file)

    else:

        agi.verbose('Error')

        file=sys.argv[1]+'outlabel'+sys.argv[2].replace(' ','')

        generate(key, u'Хотите сообщить показания другого счетчика да или нет', file+'.mp3')

        agi.set_variable('label', '5')



2018-09-29T23:27:08
Asterisk