Шрифт:
Этот добавочный номер еще не закончен, но прервемся на мгновение и посмотрим, что уже сделано.
Когда агент по продажам занимает рабочий стол, он регистрируется, набирая собственный добавочный номер. В этом случае шаблоном 110[1-5] определены номера от 1101 до 1105. Так же просто можно задать менее жесткое ограничение, используя шаблон 11XX (разрешая номера в диапазоне от 1100 до 1199). Этот добавочный номер использует func_odbc для выполнения поиска с помощью функции диалплана HOTDESK_INFO (созданием которой мы вскоре займемся). Эта специальная функция (описываемая в файле func_odbc.conf) реализует SQL-вы- ражение и возвращает все, что извлекает из базы данных. Новая функция HOTDESK_INFO будет определена в файле func_odbc.conf следующим образом:
[INFO]
prefix=HOTDESK
dsn=asterisk
read=SELECT ${ARG1} FROM ast_hotdesk WHERE extension = '${ARG2}' Лишь несколько строк, а так много всего. Давайте быстренько рассмотрим все это, прежде чем двигаться дальше.
Прежде всего, параметр prefix необязательный. Если prefix не задан, Asterisk добавляет в имя функции (в данном случае INFO) префикс ODBC, то есть эта функция будет названа ODBC_INFO. Такое имя не очень хорошо описывает назначение функции, поэтому полезно задавать префикс, который поможет связать ODBC-функции с задачами, ими выполняемыми. В данном случае мы выбрали имя HOTDESK, то есть данная специальная функция будет названа HOTDESK_INFO.
Атрибут dsn указывает Asterisk, какое из описанных в файле res_odbc. conf соединений использовать. Поскольку в res_odbc.conf может быть сконфигурировано несколько соединений, мы задаем здесь, какое именно должно использоваться. На рис. 12.1 показано отношение между различными настройками файлов и то, как они последовательно ссылаются друг на друга для соединения с базой данных.
Рис. 12.1. Отношения между func_odbc.conf, res_odbc.conf, /etc/odbc.ini (unixODBC) и соединение с базой данных
Затем описываем SQL-запрос с помощью атрибута read (чтение). Существует два разных формата вызова функций диалплана: один - для извлечения информации, а другой - для ее записи. Атрибут read используется, когда функция H0TDESK_INF0 вызывается в формате для извлечения данных (и можно выполнить отдельное SQL-выражение с атрибутом write (запись); формат для атрибута write обсуждается в данной главе несколько позже).
Для чтения значений из этой функции в диалплане используется следующий формат:
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 можно выполнять практически любые операции. Однако с точки зрения безопасности это недопустимо. Поэтому крайне желательно выполнить те рекомендации по установке, которые описаны далее в этой главе.