Есть 3 абонента А,Б,С
1) А и Б сейчас разговаривают.
2) С звонит А.
Как теперь мне реализовать следующую функциональность:
- А разговаривает с С, Б на холде
- А разговаривает с Б, С на холде
- А разговаривает с С, Б на холде
...
- А вешает трубку и все дропаются.
Средствами диалплана, АМИ, что-то еще? Мне нужна идея через что такое делать и по какому принципу. Входящих/Инициированных звонков может быть до 10(на сип-клиентах линий не хватит) и между всеми нужно уметь переключаться, никаких разрывов связи быть не должно. Спасибо!
Парковку пробовал - не получается. Если я припарковываю Б, то А отваливается. Собственно она так и работает, позволяя А совершить новый звонок к С. У меня ситуация другая. У меня 2 входящих от Б и С. И надо уметь поговорить с Б, потом с С, потом опять с Б итд. При этом А не кладет трубку вообще, никаких дтмф не нажимает и никому не звонит. Просто переключается между каналами. Команду на переключение дает стороняя программа.
У меня возникает трудность в том, что одновременно надо оперировать тремя отвеченными каналами, никого не дропнув...
Решил задачу через конференцию. Не уверен, что решение единственное, правильное и оптимальное...
И так, нам понадобится AMI и Redirect с дополнительным ExtraChannel, то есть двойной редирект. Смысл в том чтобы одновременно разорвать бридж и перебросить одного в конференцию, а второго на холд. Третьего средиректить в ту же конференцию после второй командой. Т.е:
А разговаривает с Б, С на холде. Надо: А разговаривает с С, Б на холде.
2. Редиректим с холда в конференцию.
"Action": "Redirect",
"Channel": С.channelId,
"Exten": "to-conf",
"Context": "call-services",
"Priority": "1",
Конференция потому что в конференции можно сидеть одному, звонок не теряется. Чтобы в конференции не крякали "вы один в конференции" итп, следует завести отдельные профили selector_profile,selector_user,selector_menu.
Диалплан:
[call-services]
...
exten => to-conf,1,NoOp(to-conf...)
same => n, Answer()
same => n, ConfBridge(${CONFNO},selector_profile,selector_user,selector_menu)
exten => to-hold,1,NoOp(to-hold...)
same => n, Answer()
same => n, MusicOnHold(default)
Answer() не мешает, но позволяет ответить а потом редиректить. Тут сразу возникает вопрос а в какую конференцию редиректить? А сформировать свое имя и установить его в ${CONFNO} через Varset:
"Action": "Setvar",
"Channel": канал,
"Variable": CONFNO,
"Value": confName, ; например, номер А + "-tmp-conf"
Чтобы не разбираться, можно вначале установить данную переменную всем трем каналам. Для "Ring", "Ringing", "Up" каналы есть и их можно узнать и получить. Сие прекрасно, можно редиректить входящие и исходящие, делая им Answer().
Команда на переключение должна подаваться извне. Я смог таким образом переключаться между 20 звонками совершенно спокойно и никого не теряя. Ничего больше в диалплане менять не пришлось, но если несколько линий не поддерживается (не будет состояния "Ring", а будет сразу "Busy"), то надо сразу кидать второго входящего на холд еще в диаплане.
Какие трудности:
1. Слежение за правильным состоянием каналов из AMI. Их На самом деле 4:
A - "Up"
Б - "Up"
C - "Ring"
А2 - "Ringing"
2. Разрывая бридж, всегда приходит событие MusicOnHold на А. Так же надо правильно обрабатывать хангап.
Если кому не понятно - расскажу подробнее. Критика и комментарии приветствуются.