Чтение онлайн

на главную

Жанры

Asterisk™: будущее телефонии Второе издание
Шрифт:

exten => s,n,Set(RETURNED_VALUE=${H0TDESK_INF0(status,1101)}) Это обеспечит возвращение значения, расположенного в столбце status (статус) базы данных, для которого значение столбца extension (добавочный номер) равно 1101. Переданные в функцию H0TDESK_INF0 значения столбца status и 1101 помещаются в SQL-запрос, заданный для атрибута read, и обозначаются как ${ARG1} и ${ARG2}. Если была передана третья опция, она будет доступна как ${ARG3}.

Убедитесь, что передаваемые данные достаточно уникальны и обеспечивают возвращение только одной строки. Если возвращается несколько строк, Asterisk будет видеть только первую из них. Для PostgreSQL

можно ограничить возвращаемые данные одной строкой, добавив в конец SQL-запроса LIMIT 1, но это не очень хорошая практика и она не рекомендуется к применению. Чуть дальше в этом разделе мы увидим, как использовать PostgreSQL-функции LIMIT и OFFSET для перебора нескольких строк данных!

Использование функции ARRAY

В нашем примере используется два отдельных вызова базы данных и получаемые в результате значения присваиваются двум переменным канала (${E}_STATUS и ${E}_PIN). Это было сделано с целью упростить пример:

exten => _110[1-5],n,Set(${E}_STATUS=${HOTDESK_INFO(status,${E})}) exten => _110[1-5],n,Set(${E}_PIN=${HOTDESK_INFO(pin,${E})})

В качестве альтернативы можно было бы возвращать несколько столбцов и сохранять их в разных переменных, используя функцию диалплана ARRAY (массив). Если SQL-запрос в файле func_ odbc.conf определен так:

read=SELECT pin,status FROM ast_hotdesk WHERE extension = '${E}' с помощью функции ARRAY можно в одном обращении к базе данных сохранять каждый столбец данных строки в собственной переменной:

exten => _110[1-5],n,Set(ARRAY(${E}_PIN,${E}_STATUS)=${HOTDES K_INFO(${E})})

После выполнения SQL-запроса возвращенное значение (если таковое имеется) присваивается переменной канала RETURNED_VALUE (возвращенное значение).

Итак, в первых двух строках следующего фрагмента кода мы передаем значение status и значение, содержащееся в переменной ${E} (например, 1101) в функцию HOTDESK_INFO. Затем эти два значения замещаются в SQL-запросе на ${ARG1} и ${ARG2} соответственно, SQL-запрос выполняется, а возвращенное значение присваивается переменной канала ${E}_STATUS.

Итак, теперь закончим шаблонный добавочный номер:

exten => _110[1-5],n,Set(${E}_STATUS=${HOTDESK_INFO(status,${E})}) exten => _110[1-5],n,Set(${E}_PIN=${HOTDESK_INFO(pin,${E})}) exten => _110[1-5],n,GotoIf($[${ISNULL(${${E}_STATUS})}]?invalid_user,1) ; check if ${E}_STATUS is NULL

exten => _110[1-5],n,GotoIf($[${${E}_STATUS} = 1]?logout,1:login,1) Присвоив значение столбца status переменной ${E}_STATUS (если был набран добавочный номер 1101, имя переменной было бы 1101_STATUS), проверяем, было ли возвращено значение из базы данных (контроль ошибок). Для этой проверки используем функцию ISNULL. Последняя строка фрагмента кода проверяет статус телефона, и, если в текущий момент он зарегистрирован, будет выполнен его выход из системы. Если он еще не зарегистрирован, управление перейдет к добавочному номеру login c приоритетом 1 в рамках того же контекста [117] .

117

Помните, что в традиционной телефонной системе все добавочные номера должны быть числовыми, но в Asterisk они могут быть и именованными. Возможное преимущество от применения нечислового добавочного номера в том, что абоненту будет намного сложнее набрать его с обычного телефона, а следовательно, такие номера более безопасны. В этом примере будет использоваться несколько именованных добавочных номеров. Если вы хотите быть абсолютно уверенным, что злонамеренный абонент не сможет дозвониться по этим именованным добавочным номерами, просто используйте прием, применяемый загрузчиком AEL: начинайте обработку не с приоритета 1.

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

В следующей после 1.4 версии (в настоящее время готовящейся к выпуску)

с выражениями, выполняемыми readsql, можно будет использовать переменную канала ${0DBCR0WS}. GotoIf можно заменить примерно следующим:

exten => _110[1-5],n,GotoIf($[${0DBCR0WS} < 0]?invalid_user,1)

Добавочный номер login выполняет несколько начальных проверок, чтобы убедиться в достоверности введенного агентом кода. Мы предоставляем три попытки для ввода правильного пин-кода. Если все три ввода недействительны, вызов направляется на добавочный номер login_fail (неудачная регистрация) (который будет написан позже).

exten => login,1,No0p ; задаем исходное значение счетчика

exten => login,n,Set(PIN_TRIES=0) ; задаем максимальное число попыток регистрации

exten => login,n,Set(MAX_PIN_TRIES=3)

exten => login,n(get_pin),No0p ; увеличиваем счетчик попыток ввода пин-кода exten => login,n,Set(PIN_TRIES=$[${PIN_TRIES} + 1]) exten => login,n,Read(PIN_ENTERED|enter-password|${LEN(${${E}_PIN})}) exten => login,n,GotoIf($[${PIN_ENTERED} = ${${E}_PIN}]?valid_login,1) exten => login,n,Playback(invalid-pin)

exten => login,n,GotoIf($[${PIN_TRIES} <=${MAX_PIN_TRIES}]?get_pin:login_fail,1) Если введен соответствующий пин-код, проверяем регистрационное имя с помощью добавочного номера valid_login (действительное регистрационное имя). Сначала используем переменную CHANNEL (канал), чтобы выяснить, с какого телефона выполняется звонок. Обычно значение переменной имеет примерно такой вид: SIP/desk_1-ab4034c. Поэтому с помощью функции CUT сначала отбрасываем часть строки SIP/, а оставшееся значение присваиваем переменной L0CATI0N (местоположение). Затем убираем часть строки -ab4034c, а оставшуюся строку, desk_1, присваиваем переменной L0CATI0N. exten => valid_login,1,No0p

; отбрасываем технологию канала, а оставшуюся строку сохраняем в переменной ; L0CATI0N

exten => valid_login,n,Set(L0CATI0N=${CUT(CHANNEL,/,2)}) ; отбрасываем уникальный идентификатор и сохраняем оставшуюся строку

; в переменной LOCATION

exten => valid_login,n,Set(LOCATION=${CUT(LOCATION,-,1)}) Используем еще одну специальную функцию HOTDESK_CHECK_PHONE_ LOGINS, созданную в файле func_odbc.conf, для проверки, не зарегистрирован ли по этому телефону какой-то другой пользователь. Если количество ранее зарегистрированных пользователей больше 0 (их не может быть больше 1, но мы все равно проводим проверку и сброс для всех вариантов), функция выполняет логику добавочного номера logout_login (отмена регистрации регистрационного имени). Если никто из агентов не был зарегистрирован ранее, обновляем статус регистрации для этого пользователя с помощью функции HOTDESK_ STATUS:

exten => valid_login,n,Set(ARRAY(USERS_LOGGED_IN)=${HOTDESK_CHECK_PHONE_ LOGINS(${LOCATION})})

exten => valid_login,n,GotoIf($[${USERS_LOGGED_IN} > 0]?logout_login,1) exten => valid_login,n(set_login_status),NoOp

Задаем для телефона статус '1' - здесь и происходит регистрация ПРИМЕЧАНИЕ: здесь надо экранировать запятую, потому что в приложении Set есть аргументы

exten => valid_login,n,Set(HOTDESK_STATUS(${E})=1\,${LOCATION}) exten => valid_login,n,GotoIf($[${ODBCROWS} < 1]?error,1) exten => valid_login,n,Playback(agent-loginok) exten => valid_login,n,Hangup

Создаем в файле func_odbc.conf функцию для записи следующим образом:

[STATUS]

prefix=HOTDESK

dsn=asterisk

write=UPDATE ast_hotdesk SET status = '${VAL1}', location = '${VAL2}' WHERE extension = '${ARG1}'

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

Первое, на что вы, возможно, обратили внимание, - теперь в SQL-запросе есть переменные и ${VALx}, и ${ARGx}. Они содержат значения, передаваемые нами в функцию из диалплана. В данном случае имеется две переменных VAL и одна переменная ARG, которые были заданы из диалплана посредством такого выражения: Set(HOTDESK_STATUS(${E})=1\,${LOCATION})

Поделиться:
Популярные книги

Камень. Книга пятая

Минин Станислав
5. Камень
Фантастика:
боевая фантастика
6.43
рейтинг книги
Камень. Книга пятая

Черный маг императора

Герда Александр
1. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора

Кодекс Крови. Книга VI

Борзых М.
6. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VI

Отверженный. Дилогия

Опсокополос Алексис
Отверженный
Фантастика:
фэнтези
7.51
рейтинг книги
Отверженный. Дилогия

Неудержимый. Книга XIII

Боярский Андрей
13. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XIII

Черный Маг Императора 6

Герда Александр
6. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
7.00
рейтинг книги
Черный Маг Императора 6

Начальник милиции. Книга 3

Дамиров Рафаэль
3. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 3

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Лорд Системы 13

Токсик Саша
13. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 13

На границе империй. Том 9. Часть 4

INDIGO
17. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 4

Вторая невеста Драконьего Лорда. Дилогия

Огненная Любовь
Вторая невеста Драконьего Лорда
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Вторая невеста Драконьего Лорда. Дилогия

Неудержимый. Книга X

Боярский Андрей
10. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга X

Гарем вне закона 18+

Тесленок Кирилл Геннадьевич
1. Гарем вне закона
Фантастика:
фэнтези
юмористическая фантастика
6.73
рейтинг книги
Гарем вне закона 18+

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания